File indexing completed on 2025-11-03 09:15:44
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 
0013 
0014 
0015 
0016 
0017 
0018 
0019 
0020 
0021 
0022 
0023 
0024 
0025 
0026 
0027 
0028 
0029 
0030 
0031 
0032 
0033 
0034 
0035 
0036 
0037 
0038 
0039 
0040 
0041 
0042 
0043 
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 
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 
0087 
0088 
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         
0100     }
0101 #endif
0102 };
0103 
0104 #ifdef __cplusplus
0105 
0106 #include <string>
0107 
0108 struct aiMetadata;
0109 
0110 
0111 
0112 
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 
0148 
0149 
0150 
0151 
0152 
0153 
0154 
0155 
0156 struct aiMetadata {
0157     
0158     unsigned int mNumProperties;
0159 
0160     
0161     C_STRUCT aiString *mKeys;
0162 
0163     
0164 
0165     C_STRUCT aiMetadataEntry *mValues;
0166 
0167 #ifdef __cplusplus
0168 
0169     
0170 
0171 
0172     aiMetadata() AI_NO_EXCEPT
0173             : mNumProperties(0),
0174               mKeys(nullptr),
0175               mValues(nullptr) {
0176         
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 
0257 
0258     ~aiMetadata() {
0259         delete[] mKeys;
0260         mKeys = nullptr;
0261         if (mValues) {
0262             
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             
0305             delete[] mValues;
0306             mValues = nullptr;
0307         }
0308     }
0309 
0310     
0311 
0312 
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 
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         
0358         if (index >= mNumProperties) {
0359             return false;
0360         }
0361 
0362         
0363         if (key.empty()) {
0364             return false;
0365         }
0366 
0367         
0368         mKeys[index] = key;
0369 
0370         
0371         mValues[index].mType = GetAiType(value);
0372 
0373         
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         
0410         if (index >= mNumProperties) {
0411             return false;
0412         }
0413 
0414         
0415         
0416         if (GetAiType(value) != mValues[index].mType) {
0417             return false;
0418         }
0419 
0420         
0421         
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         
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     
0444     
0445     
0446     
0447     
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     
0460     
0461     inline bool HasKey(const char *key) const {
0462         if (nullptr == key) {
0463             return false;
0464         }
0465 
0466         
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 
0569 };
0570 
0571 #endif