miniassimp

annotate include/miniassimp/metadata.h @ 0:879c81d94345

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 28 Jan 2019 18:19:26 +0200
parents
children
rev   line source
nuclear@0 1 /*
nuclear@0 2 ---------------------------------------------------------------------------
nuclear@0 3 Open Asset Import Library (assimp)
nuclear@0 4 ---------------------------------------------------------------------------
nuclear@0 5
nuclear@0 6 Copyright (c) 2006-2018, assimp team
nuclear@0 7
nuclear@0 8
nuclear@0 9
nuclear@0 10 All rights reserved.
nuclear@0 11
nuclear@0 12 Redistribution and use of this software in source and binary forms,
nuclear@0 13 with or without modification, are permitted provided that the following
nuclear@0 14 conditions are met:
nuclear@0 15
nuclear@0 16 * Redistributions of source code must retain the above
nuclear@0 17 copyright notice, this list of conditions and the
nuclear@0 18 following disclaimer.
nuclear@0 19
nuclear@0 20 * Redistributions in binary form must reproduce the above
nuclear@0 21 copyright notice, this list of conditions and the
nuclear@0 22 following disclaimer in the documentation and/or other
nuclear@0 23 materials provided with the distribution.
nuclear@0 24
nuclear@0 25 * Neither the name of the assimp team, nor the names of its
nuclear@0 26 contributors may be used to endorse or promote products
nuclear@0 27 derived from this software without specific prior
nuclear@0 28 written permission of the assimp team.
nuclear@0 29
nuclear@0 30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
nuclear@0 31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
nuclear@0 32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
nuclear@0 33 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
nuclear@0 34 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
nuclear@0 35 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
nuclear@0 36 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
nuclear@0 37 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
nuclear@0 38 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
nuclear@0 39 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nuclear@0 40 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nuclear@0 41 ---------------------------------------------------------------------------
nuclear@0 42 */
nuclear@0 43
nuclear@0 44 /** @file metadata.h
nuclear@0 45 * @brief Defines the data structures for holding node meta information.
nuclear@0 46 */
nuclear@0 47 #pragma once
nuclear@0 48 #ifndef AI_METADATA_H_INC
nuclear@0 49 #define AI_METADATA_H_INC
nuclear@0 50
nuclear@0 51 #if defined(_MSC_VER) && (_MSC_VER <= 1500)
nuclear@0 52 # include "Compiler/pstdint.h"
nuclear@0 53 #else
nuclear@0 54 # include <inttypes.h>
nuclear@0 55 #endif
nuclear@0 56
nuclear@0 57 // -------------------------------------------------------------------------------
nuclear@0 58 /**
nuclear@0 59 * Enum used to distinguish data types
nuclear@0 60 */
nuclear@0 61 // -------------------------------------------------------------------------------
nuclear@0 62 typedef enum aiMetadataType {
nuclear@0 63 AI_BOOL = 0,
nuclear@0 64 AI_INT32 = 1,
nuclear@0 65 AI_UINT64 = 2,
nuclear@0 66 AI_FLOAT = 3,
nuclear@0 67 AI_DOUBLE = 4,
nuclear@0 68 AI_AISTRING = 5,
nuclear@0 69 AI_AIVECTOR3D = 6,
nuclear@0 70 AI_META_MAX = 7,
nuclear@0 71
nuclear@0 72 #ifndef SWIG
nuclear@0 73 FORCE_32BIT = INT_MAX
nuclear@0 74 #endif
nuclear@0 75 } aiMetadataType;
nuclear@0 76
nuclear@0 77 // -------------------------------------------------------------------------------
nuclear@0 78 /**
nuclear@0 79 * Metadata entry
nuclear@0 80 *
nuclear@0 81 * The type field uniquely identifies the underlying type of the data field
nuclear@0 82 */
nuclear@0 83 // -------------------------------------------------------------------------------
nuclear@0 84 struct aiMetadataEntry {
nuclear@0 85 aiMetadataType mType;
nuclear@0 86 void* mData;
nuclear@0 87 };
nuclear@0 88
nuclear@0 89 #ifdef __cplusplus
nuclear@0 90
nuclear@0 91 #include <string>
nuclear@0 92
nuclear@0 93 // -------------------------------------------------------------------------------
nuclear@0 94 /**
nuclear@0 95 * Helper functions to get the aiType enum entry for a type
nuclear@0 96 */
nuclear@0 97 // -------------------------------------------------------------------------------
nuclear@0 98
nuclear@0 99 inline aiMetadataType GetAiType( bool ) { return AI_BOOL; }
nuclear@0 100 inline aiMetadataType GetAiType( int32_t ) { return AI_INT32; }
nuclear@0 101 inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; }
nuclear@0 102 inline aiMetadataType GetAiType( float ) { return AI_FLOAT; }
nuclear@0 103 inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; }
nuclear@0 104 inline aiMetadataType GetAiType( const aiString & ) { return AI_AISTRING; }
nuclear@0 105 inline aiMetadataType GetAiType( const aiVector3D & ) { return AI_AIVECTOR3D; }
nuclear@0 106
nuclear@0 107 #endif // __cplusplus
nuclear@0 108
nuclear@0 109 // -------------------------------------------------------------------------------
nuclear@0 110 /**
nuclear@0 111 * Container for holding metadata.
nuclear@0 112 *
nuclear@0 113 * Metadata is a key-value store using string keys and values.
nuclear@0 114 */
nuclear@0 115 // -------------------------------------------------------------------------------
nuclear@0 116 struct aiMetadata {
nuclear@0 117 /** Length of the mKeys and mValues arrays, respectively */
nuclear@0 118 unsigned int mNumProperties;
nuclear@0 119
nuclear@0 120 /** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
nuclear@0 121 C_STRUCT aiString* mKeys;
nuclear@0 122
nuclear@0 123 /** Arrays of values, may not be NULL. Entries in this array may be NULL if the
nuclear@0 124 * corresponding property key has no assigned value. */
nuclear@0 125 C_STRUCT aiMetadataEntry* mValues;
nuclear@0 126
nuclear@0 127 #ifdef __cplusplus
nuclear@0 128
nuclear@0 129 /**
nuclear@0 130 * @brief The default constructor, set all members to zero by default.
nuclear@0 131 */
nuclear@0 132 aiMetadata() AI_NO_EXCEPT
nuclear@0 133 : mNumProperties(0)
nuclear@0 134 , mKeys(0)
nuclear@0 135 , mValues(0) {
nuclear@0 136 // empty
nuclear@0 137 }
nuclear@0 138
nuclear@0 139 aiMetadata( const aiMetadata &rhs )
nuclear@0 140 : mNumProperties( rhs.mNumProperties )
nuclear@0 141 , mKeys( 0 )
nuclear@0 142 , mValues( 0 ) {
nuclear@0 143 mKeys = new aiString[ mNumProperties ];
nuclear@0 144 for ( size_t i = 0; i < static_cast<size_t>( mNumProperties ); ++i ) {
nuclear@0 145 mKeys[ i ] = rhs.mKeys[ i ];
nuclear@0 146 }
nuclear@0 147 mValues = new aiMetadataEntry[ mNumProperties ];
nuclear@0 148 for ( size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i ) {
nuclear@0 149 mValues[ i ].mType = rhs.mValues[ i ].mType;
nuclear@0 150 switch ( rhs.mValues[ i ].mType ) {
nuclear@0 151 case AI_BOOL:
nuclear@0 152 mValues[ i ].mData = new bool;
nuclear@0 153 ::memcpy( mValues[ i ].mData, rhs.mValues[ i ].mData, sizeof(bool) );
nuclear@0 154 break;
nuclear@0 155 case AI_INT32: {
nuclear@0 156 int32_t v;
nuclear@0 157 ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( int32_t ) );
nuclear@0 158 mValues[ i ].mData = new int32_t( v );
nuclear@0 159 }
nuclear@0 160 break;
nuclear@0 161 case AI_UINT64: {
nuclear@0 162 uint64_t v;
nuclear@0 163 ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( uint64_t ) );
nuclear@0 164 mValues[ i ].mData = new uint64_t( v );
nuclear@0 165 }
nuclear@0 166 break;
nuclear@0 167 case AI_FLOAT: {
nuclear@0 168 float v;
nuclear@0 169 ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( float ) );
nuclear@0 170 mValues[ i ].mData = new float( v );
nuclear@0 171 }
nuclear@0 172 break;
nuclear@0 173 case AI_DOUBLE: {
nuclear@0 174 double v;
nuclear@0 175 ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( double ) );
nuclear@0 176 mValues[ i ].mData = new double( v );
nuclear@0 177 }
nuclear@0 178 break;
nuclear@0 179 case AI_AISTRING: {
nuclear@0 180 aiString v;
nuclear@0 181 rhs.Get<aiString>( mKeys[ i ], v );
nuclear@0 182 mValues[ i ].mData = new aiString( v );
nuclear@0 183 }
nuclear@0 184 break;
nuclear@0 185 case AI_AIVECTOR3D: {
nuclear@0 186 aiVector3D v;
nuclear@0 187 rhs.Get<aiVector3D>( mKeys[ i ], v );
nuclear@0 188 mValues[ i ].mData = new aiVector3D( v );
nuclear@0 189 }
nuclear@0 190 break;
nuclear@0 191 #ifndef SWIG
nuclear@0 192 case FORCE_32BIT:
nuclear@0 193 #endif
nuclear@0 194 default:
nuclear@0 195 break;
nuclear@0 196 }
nuclear@0 197
nuclear@0 198 }
nuclear@0 199 }
nuclear@0 200
nuclear@0 201 /**
nuclear@0 202 * @brief The destructor.
nuclear@0 203 */
nuclear@0 204 ~aiMetadata() {
nuclear@0 205 delete [] mKeys;
nuclear@0 206 mKeys = 0;
nuclear@0 207 if (mValues) {
nuclear@0 208 // Delete each metadata entry
nuclear@0 209 for (unsigned i=0; i<mNumProperties; ++i) {
nuclear@0 210 void* data = mValues[i].mData;
nuclear@0 211 switch (mValues[i].mType) {
nuclear@0 212 case AI_BOOL:
nuclear@0 213 delete static_cast< bool* >( data );
nuclear@0 214 break;
nuclear@0 215 case AI_INT32:
nuclear@0 216 delete static_cast< int32_t* >( data );
nuclear@0 217 break;
nuclear@0 218 case AI_UINT64:
nuclear@0 219 delete static_cast< uint64_t* >( data );
nuclear@0 220 break;
nuclear@0 221 case AI_FLOAT:
nuclear@0 222 delete static_cast< float* >( data );
nuclear@0 223 break;
nuclear@0 224 case AI_DOUBLE:
nuclear@0 225 delete static_cast< double* >( data );
nuclear@0 226 break;
nuclear@0 227 case AI_AISTRING:
nuclear@0 228 delete static_cast< aiString* >( data );
nuclear@0 229 break;
nuclear@0 230 case AI_AIVECTOR3D:
nuclear@0 231 delete static_cast< aiVector3D* >( data );
nuclear@0 232 break;
nuclear@0 233 #ifndef SWIG
nuclear@0 234 case FORCE_32BIT:
nuclear@0 235 #endif
nuclear@0 236 default:
nuclear@0 237 break;
nuclear@0 238 }
nuclear@0 239 }
nuclear@0 240
nuclear@0 241 // Delete the metadata array
nuclear@0 242 delete [] mValues;
nuclear@0 243 mValues = 0;
nuclear@0 244 }
nuclear@0 245 }
nuclear@0 246
nuclear@0 247 /**
nuclear@0 248 * @brief Allocates property fields + keys.
nuclear@0 249 * @param numProperties Number of requested properties.
nuclear@0 250 */
nuclear@0 251 static inline
nuclear@0 252 aiMetadata *Alloc( unsigned int numProperties ) {
nuclear@0 253 if ( 0 == numProperties ) {
nuclear@0 254 return 0;
nuclear@0 255 }
nuclear@0 256
nuclear@0 257 aiMetadata *data = new aiMetadata;
nuclear@0 258 data->mNumProperties = numProperties;
nuclear@0 259 data->mKeys = new aiString[ data->mNumProperties ]();
nuclear@0 260 data->mValues = new aiMetadataEntry[ data->mNumProperties ]();
nuclear@0 261
nuclear@0 262 return data;
nuclear@0 263 }
nuclear@0 264
nuclear@0 265 /**
nuclear@0 266 * @brief Deallocates property fields + keys.
nuclear@0 267 */
nuclear@0 268 static inline
nuclear@0 269 void Dealloc( aiMetadata *metadata ) {
nuclear@0 270 delete metadata;
nuclear@0 271 }
nuclear@0 272
nuclear@0 273 template<typename T>
nuclear@0 274 inline
nuclear@0 275 void Add(const std::string& key, const T& value) {
nuclear@0 276 aiString* new_keys = new aiString[mNumProperties + 1];
nuclear@0 277 aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1];
nuclear@0 278
nuclear@0 279 for(unsigned int i = 0; i < mNumProperties; ++i)
nuclear@0 280 {
nuclear@0 281 new_keys[i] = mKeys[i];
nuclear@0 282 new_values[i] = mValues[i];
nuclear@0 283 }
nuclear@0 284
nuclear@0 285 delete mKeys;
nuclear@0 286 delete mValues;
nuclear@0 287
nuclear@0 288 mKeys = new_keys;
nuclear@0 289 mValues = new_values;
nuclear@0 290
nuclear@0 291 mNumProperties++;
nuclear@0 292
nuclear@0 293 Set(mNumProperties - 1, key, value);
nuclear@0 294 }
nuclear@0 295
nuclear@0 296 template<typename T>
nuclear@0 297 inline
nuclear@0 298 bool Set( unsigned index, const std::string& key, const T& value ) {
nuclear@0 299 // In range assertion
nuclear@0 300 if ( index >= mNumProperties ) {
nuclear@0 301 return false;
nuclear@0 302 }
nuclear@0 303
nuclear@0 304 // Ensure that we have a valid key.
nuclear@0 305 if ( key.empty() ) {
nuclear@0 306 return false;
nuclear@0 307 }
nuclear@0 308
nuclear@0 309 // Set metadata key
nuclear@0 310 mKeys[index] = key;
nuclear@0 311
nuclear@0 312 // Set metadata type
nuclear@0 313 mValues[index].mType = GetAiType(value);
nuclear@0 314 // Copy the given value to the dynamic storage
nuclear@0 315 mValues[index].mData = new T(value);
nuclear@0 316
nuclear@0 317 return true;
nuclear@0 318 }
nuclear@0 319
nuclear@0 320 template<typename T>
nuclear@0 321 inline
nuclear@0 322 bool Get( unsigned index, T& value ) const {
nuclear@0 323 // In range assertion
nuclear@0 324 if ( index >= mNumProperties ) {
nuclear@0 325 return false;
nuclear@0 326 }
nuclear@0 327
nuclear@0 328 // Return false if the output data type does
nuclear@0 329 // not match the found value's data type
nuclear@0 330 if ( GetAiType( value ) != mValues[ index ].mType ) {
nuclear@0 331 return false;
nuclear@0 332 }
nuclear@0 333
nuclear@0 334 // Otherwise, output the found value and
nuclear@0 335 // return true
nuclear@0 336 value = *static_cast<T*>(mValues[index].mData);
nuclear@0 337
nuclear@0 338 return true;
nuclear@0 339 }
nuclear@0 340
nuclear@0 341 template<typename T>
nuclear@0 342 inline
nuclear@0 343 bool Get( const aiString& key, T& value ) const {
nuclear@0 344 // Search for the given key
nuclear@0 345 for ( unsigned int i = 0; i < mNumProperties; ++i ) {
nuclear@0 346 if ( mKeys[ i ] == key ) {
nuclear@0 347 return Get( i, value );
nuclear@0 348 }
nuclear@0 349 }
nuclear@0 350 return false;
nuclear@0 351 }
nuclear@0 352
nuclear@0 353 template<typename T>
nuclear@0 354 inline
nuclear@0 355 bool Get( const std::string& key, T& value ) const {
nuclear@0 356 return Get(aiString(key), value);
nuclear@0 357 }
nuclear@0 358
nuclear@0 359 /// Return metadata entry for analyzing it by user.
nuclear@0 360 /// \param [in] pIndex - index of the entry.
nuclear@0 361 /// \param [out] pKey - pointer to the key value.
nuclear@0 362 /// \param [out] pEntry - pointer to the entry: type and value.
nuclear@0 363 /// \return false - if pIndex is out of range, else - true.
nuclear@0 364 inline
nuclear@0 365 bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) const {
nuclear@0 366 if ( index >= mNumProperties ) {
nuclear@0 367 return false;
nuclear@0 368 }
nuclear@0 369
nuclear@0 370 key = &mKeys[index];
nuclear@0 371 entry = &mValues[index];
nuclear@0 372
nuclear@0 373 return true;
nuclear@0 374 }
nuclear@0 375
nuclear@0 376 #endif // __cplusplus
nuclear@0 377
nuclear@0 378 };
nuclear@0 379
nuclear@0 380 #endif // AI_METADATA_H_INC