Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 09:30:09

0001 /*
0002 ---------------------------------------------------------------------------
0003 Open Asset Import Library (assimp)
0004 ---------------------------------------------------------------------------
0005 
0006 Copyright (c) 2006-2024, assimp team
0007 
0008 All rights reserved.
0009 
0010 Redistribution and use of this software in source and binary forms,
0011 with or without modification, are permitted provided that the following
0012 conditions are met:
0013 
0014 * Redistributions of source code must retain the above
0015   copyright notice, this list of conditions and the
0016   following disclaimer.
0017 
0018 * Redistributions in binary form must reproduce the above
0019   copyright notice, this list of conditions and the
0020   following disclaimer in the documentation and/or other
0021   materials provided with the distribution.
0022 
0023 * Neither the name of the assimp team, nor the names of its
0024   contributors may be used to endorse or promote products
0025   derived from this software without specific prior
0026   written permission of the assimp team.
0027 
0028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0029 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0030 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0031 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0032 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0033 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0034 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0035 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0036 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0038 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0039 ---------------------------------------------------------------------------
0040 */
0041 
0042 /** @file metadata.h
0043  *  @brief Defines the data structures for holding node meta information.
0044  */
0045 #pragma once
0046 #ifndef AI_METADATA_H_INC
0047 #define AI_METADATA_H_INC
0048 
0049 #ifdef __GNUC__
0050 #pragma GCC system_header
0051 #endif
0052 
0053 #if defined(_MSC_VER) && (_MSC_VER <= 1500)
0054 #include "Compiler/pstdint.h"
0055 #else
0056 #include <stdint.h>
0057 #endif
0058 
0059 #include <assimp/quaternion.h>
0060 
0061 // -------------------------------------------------------------------------------
0062 /**
0063   * Enum used to distinguish data types
0064   */
0065 // -------------------------------------------------------------------------------
0066 typedef enum aiMetadataType {
0067     AI_BOOL = 0,
0068     AI_INT32 = 1,
0069     AI_UINT64 = 2,
0070     AI_FLOAT = 3,
0071     AI_DOUBLE = 4,
0072     AI_AISTRING = 5,
0073     AI_AIVECTOR3D = 6,
0074     AI_AIMETADATA = 7,
0075     AI_INT64 = 8,
0076     AI_UINT32 = 9,
0077     AI_META_MAX = 10,
0078 
0079 #ifndef SWIG
0080     FORCE_32BIT = INT_MAX
0081 #endif
0082 } aiMetadataType;
0083 
0084 // -------------------------------------------------------------------------------
0085 /**
0086   * Metadata entry
0087   *
0088   * The type field uniquely identifies the underlying type of the data field
0089   */
0090 // -------------------------------------------------------------------------------
0091 struct aiMetadataEntry {
0092     aiMetadataType mType;
0093     void *mData;
0094 
0095 #ifdef __cplusplus
0096     aiMetadataEntry() :
0097             mType(AI_META_MAX),
0098             mData( nullptr ) {
0099         // empty
0100     }
0101 #endif
0102 };
0103 
0104 #ifdef __cplusplus
0105 
0106 #include <string>
0107 
0108 struct aiMetadata;
0109 
0110 // -------------------------------------------------------------------------------
0111 /**
0112   * Helper functions to get the aiType enum entry for a type
0113   */
0114 // -------------------------------------------------------------------------------
0115 
0116 inline aiMetadataType GetAiType(const bool &) {
0117     return AI_BOOL;
0118 }
0119 inline aiMetadataType GetAiType(int32_t) {
0120     return AI_INT32;
0121 }
0122 inline aiMetadataType GetAiType(const uint64_t &) {
0123     return AI_UINT64;
0124 }
0125 inline aiMetadataType GetAiType(const float &) {
0126     return AI_FLOAT;
0127 }
0128 inline aiMetadataType GetAiType(const double &) {
0129     return AI_DOUBLE;
0130 }
0131 inline aiMetadataType GetAiType(const aiString &) {
0132     return AI_AISTRING;
0133 }
0134 inline aiMetadataType GetAiType(const aiVector3D &) {
0135     return AI_AIVECTOR3D;
0136 }
0137 inline aiMetadataType GetAiType(const aiMetadata &) {
0138     return AI_AIMETADATA;
0139 }
0140 inline aiMetadataType GetAiType(const int64_t &) {
0141     return AI_INT64;
0142 }
0143 inline aiMetadataType GetAiType(const uint32_t &) {
0144     return AI_UINT32;
0145 }
0146 
0147 #endif // __cplusplus
0148 
0149 // -------------------------------------------------------------------------------
0150 /**
0151   * Container for holding metadata.
0152   *
0153   * Metadata is a key-value store using string keys and values.
0154   */
0155 // -------------------------------------------------------------------------------
0156 struct aiMetadata {
0157     /** Length of the mKeys and mValues arrays, respectively */
0158     unsigned int mNumProperties;
0159 
0160     /** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
0161     C_STRUCT aiString *mKeys;
0162 
0163     /** Arrays of values, may not be NULL. Entries in this array may be NULL if the
0164       * corresponding property key has no assigned value. */
0165     C_STRUCT aiMetadataEntry *mValues;
0166 
0167 #ifdef __cplusplus
0168 
0169     /**
0170      *  @brief  The default constructor, set all members to zero by default.
0171      */
0172     aiMetadata() AI_NO_EXCEPT
0173             : mNumProperties(0),
0174               mKeys(nullptr),
0175               mValues(nullptr) {
0176         // empty
0177     }
0178 
0179     aiMetadata(const aiMetadata &rhs) :
0180             mNumProperties(rhs.mNumProperties), mKeys(nullptr), mValues(nullptr) {
0181         mKeys = new aiString[mNumProperties];
0182         for (size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i) {
0183             mKeys[i] = rhs.mKeys[i];
0184         }
0185         mValues = new aiMetadataEntry[mNumProperties];
0186         for (size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i) {
0187             mValues[i].mType = rhs.mValues[i].mType;
0188             switch (rhs.mValues[i].mType) {
0189             case AI_BOOL:
0190                 mValues[i].mData = new bool;
0191                 ::memcpy(mValues[i].mData, rhs.mValues[i].mData, sizeof(bool));
0192                 break;
0193             case AI_INT32: {
0194                 int32_t v;
0195                 ::memcpy(&v, rhs.mValues[i].mData, sizeof(int32_t));
0196                 mValues[i].mData = new int32_t(v);
0197             } break;
0198             case AI_UINT64: {
0199                 uint64_t v;
0200                 ::memcpy(&v, rhs.mValues[i].mData, sizeof(uint64_t));
0201                 mValues[i].mData = new uint64_t(v);
0202             } break;
0203             case AI_FLOAT: {
0204                 float v;
0205                 ::memcpy(&v, rhs.mValues[i].mData, sizeof(float));
0206                 mValues[i].mData = new float(v);
0207             } break;
0208             case AI_DOUBLE: {
0209                 double v;
0210                 ::memcpy(&v, rhs.mValues[i].mData, sizeof(double));
0211                 mValues[i].mData = new double(v);
0212             } break;
0213             case AI_AISTRING: {
0214                 aiString v;
0215                 rhs.Get<aiString>(static_cast<unsigned int>(i), v);
0216                 mValues[i].mData = new aiString(v);
0217             } break;
0218             case AI_AIVECTOR3D: {
0219                 aiVector3D v;
0220                 rhs.Get<aiVector3D>(static_cast<unsigned int>(i), v);
0221                 mValues[i].mData = new aiVector3D(v);
0222             } break;
0223             case AI_AIMETADATA: {
0224                 aiMetadata v;
0225                 rhs.Get<aiMetadata>(static_cast<unsigned int>(i), v);
0226                 mValues[i].mData = new aiMetadata(v);
0227             } break;
0228             case AI_INT64: {
0229                 int64_t v;
0230                 ::memcpy(&v, rhs.mValues[i].mData, sizeof(int64_t));
0231                 mValues[i].mData = new int64_t(v);
0232             } break;
0233             case AI_UINT32: {
0234                 uint32_t v;
0235                 ::memcpy(&v, rhs.mValues[i].mData, sizeof(uint32_t));
0236                 mValues[i].mData = new uint32_t(v);
0237             } break;
0238 #ifndef SWIG
0239             case FORCE_32BIT:
0240 #endif
0241             default:
0242                 break;
0243             }
0244         }
0245     }
0246 
0247     aiMetadata &operator=(aiMetadata rhs) {
0248         using std::swap;
0249         swap(mNumProperties, rhs.mNumProperties);
0250         swap(mKeys, rhs.mKeys);
0251         swap(mValues, rhs.mValues);
0252         return *this;
0253     }
0254 
0255     /**
0256      *  @brief The destructor.
0257      */
0258     ~aiMetadata() {
0259         delete[] mKeys;
0260         mKeys = nullptr;
0261         if (mValues) {
0262             // Delete each metadata entry
0263             for (unsigned i = 0; i < mNumProperties; ++i) {
0264                 void *data = mValues[i].mData;
0265                 switch (mValues[i].mType) {
0266                 case AI_BOOL:
0267                     delete static_cast<bool *>(data);
0268                     break;
0269                 case AI_INT32:
0270                     delete static_cast<int32_t *>(data);
0271                     break;
0272                 case AI_UINT64:
0273                     delete static_cast<uint64_t *>(data);
0274                     break;
0275                 case AI_FLOAT:
0276                     delete static_cast<float *>(data);
0277                     break;
0278                 case AI_DOUBLE:
0279                     delete static_cast<double *>(data);
0280                     break;
0281                 case AI_AISTRING:
0282                     delete static_cast<aiString *>(data);
0283                     break;
0284                 case AI_AIVECTOR3D:
0285                     delete static_cast<aiVector3D *>(data);
0286                     break;
0287                 case AI_AIMETADATA:
0288                     delete static_cast<aiMetadata *>(data);
0289                     break;
0290                 case AI_INT64:
0291                     delete static_cast<int64_t *>(data);
0292                     break;
0293                 case AI_UINT32:
0294                     delete static_cast<uint32_t *>(data);
0295                     break;
0296 #ifndef SWIG
0297                 case FORCE_32BIT:
0298 #endif
0299                 default:
0300                     break;
0301                 }
0302             }
0303 
0304             // Delete the metadata array
0305             delete[] mValues;
0306             mValues = nullptr;
0307         }
0308     }
0309 
0310     /**
0311      *  @brief Allocates property fields + keys.
0312      *  @param  numProperties   Number of requested properties.
0313      */
0314     static inline aiMetadata *Alloc(unsigned int numProperties) {
0315         if (0 == numProperties) {
0316             return nullptr;
0317         }
0318 
0319         aiMetadata *data = new aiMetadata;
0320         data->mNumProperties = numProperties;
0321         data->mKeys = new aiString[data->mNumProperties]();
0322         data->mValues = new aiMetadataEntry[data->mNumProperties]();
0323 
0324         return data;
0325     }
0326 
0327     /**
0328      *  @brief Deallocates property fields + keys.
0329      */
0330     static inline void Dealloc(aiMetadata *metadata) {
0331         delete metadata;
0332     }
0333 
0334     template <typename T>
0335     inline void Add(const std::string &key, const T &value) {
0336         aiString *new_keys = new aiString[mNumProperties + 1];
0337         aiMetadataEntry *new_values = new aiMetadataEntry[mNumProperties + 1];
0338 
0339         for (unsigned int i = 0; i < mNumProperties; ++i) {
0340             new_keys[i] = mKeys[i];
0341             new_values[i] = mValues[i];
0342         }
0343 
0344         delete[] mKeys;
0345         delete[] mValues;
0346 
0347         mKeys = new_keys;
0348         mValues = new_values;
0349 
0350         mNumProperties++;
0351 
0352         Set(mNumProperties - 1, key, value);
0353     }
0354 
0355     template <typename T>
0356     inline bool Set(unsigned index, const std::string &key, const T &value) {
0357         // In range assertion
0358         if (index >= mNumProperties) {
0359             return false;
0360         }
0361 
0362         // Ensure that we have a valid key.
0363         if (key.empty()) {
0364             return false;
0365         }
0366 
0367         // Set metadata key
0368         mKeys[index] = key;
0369 
0370         // Set metadata type
0371         mValues[index].mType = GetAiType(value);
0372 
0373         // Copy the given value to the dynamic storage
0374         if (nullptr != mValues[index].mData && AI_AIMETADATA != mValues[index].mType) {
0375             ::memcpy(mValues[index].mData, &value, sizeof(T));
0376         } else if (nullptr != mValues[index].mData && AI_AIMETADATA == mValues[index].mType) {
0377             *static_cast<T *>(mValues[index].mData) = value;
0378         } else {
0379             if (nullptr != mValues[index].mData) {
0380                 delete static_cast<T *>(mValues[index].mData);
0381                 mValues[index].mData = nullptr;
0382             }
0383             mValues[index].mData = new T(value);
0384         }
0385 
0386         return true;
0387     }
0388 
0389     template <typename T>
0390     inline bool Set(const std::string &key, const T &value) {
0391         if (key.empty()) {
0392             return false;
0393         }
0394 
0395         bool result = false;
0396         for (unsigned int i = 0; i < mNumProperties; ++i) {
0397             if (key == mKeys[i].C_Str()) {
0398                 Set(i, key, value);
0399                 result = true;
0400                 break;
0401             }
0402         }
0403 
0404         return result;
0405     }
0406 
0407     template <typename T>
0408     inline bool Get(unsigned index, T &value) const {
0409         // In range assertion
0410         if (index >= mNumProperties) {
0411             return false;
0412         }
0413 
0414         // Return false if the output data type does
0415         // not match the found value's data type
0416         if (GetAiType(value) != mValues[index].mType) {
0417             return false;
0418         }
0419 
0420         // Otherwise, output the found value and
0421         // return true
0422         value = *static_cast<T *>(mValues[index].mData);
0423 
0424         return true;
0425     }
0426 
0427     template <typename T>
0428     inline bool Get(const aiString &key, T &value) const {
0429         // Search for the given key
0430         for (unsigned int i = 0; i < mNumProperties; ++i) {
0431             if (mKeys[i] == key) {
0432                 return Get(i, value);
0433             }
0434         }
0435         return false;
0436     }
0437 
0438     template <typename T>
0439     inline bool Get(const std::string &key, T &value) const {
0440         return Get(aiString(key), value);
0441     }
0442 
0443     /// Return metadata entry for analyzing it by user.
0444     /// \param [in] pIndex - index of the entry.
0445     /// \param [out] pKey - pointer to the key value.
0446     /// \param [out] pEntry - pointer to the entry: type and value.
0447     /// \return false - if pIndex is out of range, else - true.
0448     inline bool Get(size_t index, const aiString *&key, const aiMetadataEntry *&entry) const {
0449         if (index >= mNumProperties) {
0450             return false;
0451         }
0452 
0453         key = &mKeys[index];
0454         entry = &mValues[index];
0455 
0456         return true;
0457     }
0458 
0459     /// Check whether there is a metadata entry for the given key.
0460     /// \param [in] Key - the key value value to check for.
0461     inline bool HasKey(const char *key) const {
0462         if (nullptr == key) {
0463             return false;
0464         }
0465 
0466         // Search for the given key
0467         for (unsigned int i = 0; i < mNumProperties; ++i) {
0468             if (0 == strncmp(mKeys[i].C_Str(), key, mKeys[i].length)) {
0469                 return true;
0470             }
0471         }
0472         return false;
0473     }
0474 
0475     friend bool CompareKeys(const aiMetadata &lhs, const aiMetadata &rhs) {
0476         if (lhs.mNumProperties != rhs.mNumProperties) {
0477             return false;
0478         }
0479 
0480         for (unsigned int i = 0; i < lhs.mNumProperties; ++i) {
0481             if (lhs.mKeys[i] != rhs.mKeys[i]) {
0482                 return false;
0483             }
0484         }
0485         return true;
0486     }
0487 
0488     friend bool CompareValues(const aiMetadata &lhs, const aiMetadata &rhs) {
0489         if (lhs.mNumProperties != rhs.mNumProperties) {
0490             return false;
0491         }
0492 
0493         for (unsigned int i = 0; i < lhs.mNumProperties; ++i) {
0494             if (lhs.mValues[i].mType != rhs.mValues[i].mType) {
0495                 return false;
0496             }
0497 
0498             switch (lhs.mValues[i].mType) {
0499             case AI_BOOL: {
0500                 if (*static_cast<bool *>(lhs.mValues[i].mData) != *static_cast<bool *>(rhs.mValues[i].mData)) {
0501                     return false;
0502                 }
0503             } break;
0504             case AI_INT32: {
0505                 if (*static_cast<int32_t *>(lhs.mValues[i].mData) != *static_cast<int32_t *>(rhs.mValues[i].mData)) {
0506                     return false;
0507                 }
0508             } break;
0509             case AI_UINT64: {
0510                 if (*static_cast<uint64_t *>(lhs.mValues[i].mData) != *static_cast<uint64_t *>(rhs.mValues[i].mData)) {
0511                     return false;
0512                 }
0513             } break;
0514             case AI_FLOAT: {
0515                 if (*static_cast<float *>(lhs.mValues[i].mData) != *static_cast<float *>(rhs.mValues[i].mData)) {
0516                     return false;
0517                 }
0518             } break;
0519             case AI_DOUBLE: {
0520                 if (*static_cast<double *>(lhs.mValues[i].mData) != *static_cast<double *>(rhs.mValues[i].mData)) {
0521                     return false;
0522                 }
0523             } break;
0524             case AI_AISTRING: {
0525                 if (*static_cast<aiString *>(lhs.mValues[i].mData) != *static_cast<aiString *>(rhs.mValues[i].mData)) {
0526                     return false;
0527                 }
0528             } break;
0529             case AI_AIVECTOR3D: {
0530                 if (*static_cast<aiVector3D *>(lhs.mValues[i].mData) != *static_cast<aiVector3D *>(rhs.mValues[i].mData)) {
0531                     return false;
0532                 }
0533             } break;
0534             case AI_AIMETADATA: {
0535                 if (*static_cast<aiMetadata *>(lhs.mValues[i].mData) != *static_cast<aiMetadata *>(rhs.mValues[i].mData)) {
0536                     return false;
0537                 }
0538             } break;
0539             case AI_INT64: {
0540                 if (*static_cast<int64_t *>(lhs.mValues[i].mData) != *static_cast<int64_t *>(rhs.mValues[i].mData)) {
0541                     return false;
0542                 }
0543             } break;
0544             case AI_UINT32: {
0545                 if (*static_cast<uint32_t *>(lhs.mValues[i].mData) != *static_cast<uint32_t *>(rhs.mValues[i].mData)) {
0546                     return false;
0547                 }
0548             } break;
0549 #ifndef SWIG
0550             case FORCE_32BIT:
0551 #endif
0552             default:
0553                 break;
0554             }
0555         }
0556 
0557         return true;
0558     }
0559 
0560     friend bool operator==(const aiMetadata &lhs, const aiMetadata &rhs) {
0561         return CompareKeys(lhs, rhs) && CompareValues(lhs, rhs);
0562     }
0563 
0564     friend bool operator!=(const aiMetadata &lhs, const aiMetadata &rhs) {
0565         return !(lhs == rhs);
0566     }
0567 
0568 #endif // __cplusplus
0569 };
0570 
0571 #endif // AI_METADATA_H_INC