miniassimp

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