1/*
2---------------------------------------------------------------------------
3Open Asset Import Library (assimp)
4---------------------------------------------------------------------------
5
6Copyright (c) 2006-2019, assimp team
7
8
9
10All rights reserved.
11
12Redistribution and use of this software in source and binary forms,
13with or without modification, are permitted provided that the following
14conditions are met:
15
16* Redistributions of source code must retain the above
17 copyright notice, this list of conditions and the
18 following disclaimer.
19
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.
24
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.
29
30THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41---------------------------------------------------------------------------
42*/
43
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
50
51#if defined(_MSC_VER) && (_MSC_VER <= 1500)
52# include "Compiler/pstdint.h"
53#else
54# include <stdint.h>
55#endif
56
57// -------------------------------------------------------------------------------
58/**
59 * Enum used to distinguish data types
60 */
61 // -------------------------------------------------------------------------------
62typedef 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,
71
72#ifndef SWIG
73 FORCE_32BIT = INT_MAX
74#endif
75} aiMetadataType;
76
77// -------------------------------------------------------------------------------
78/**
79 * Metadata entry
80 *
81 * The type field uniquely identifies the underlying type of the data field
82 */
83 // -------------------------------------------------------------------------------
84struct aiMetadataEntry {
85 aiMetadataType mType;
86 void* mData;
87};
88
89#ifdef __cplusplus
90
91#include <string>
92
93// -------------------------------------------------------------------------------
94/**
95 * Helper functions to get the aiType enum entry for a type
96 */
97 // -------------------------------------------------------------------------------
98
99inline aiMetadataType GetAiType( bool ) { return AI_BOOL; }
100inline aiMetadataType GetAiType( int32_t ) { return AI_INT32; }
101inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; }
102inline aiMetadataType GetAiType( float ) { return AI_FLOAT; }
103inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; }
104inline aiMetadataType GetAiType( const aiString & ) { return AI_AISTRING; }
105inline aiMetadataType GetAiType( const aiVector3D & ) { return AI_AIVECTOR3D; }
106
107#endif // __cplusplus
108
109// -------------------------------------------------------------------------------
110/**
111 * Container for holding metadata.
112 *
113 * Metadata is a key-value store using string keys and values.
114 */
115 // -------------------------------------------------------------------------------
116struct aiMetadata {
117 /** Length of the mKeys and mValues arrays, respectively */
118 unsigned int mNumProperties;
119
120 /** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
121 C_STRUCT aiString* mKeys;
122
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;
126
127#ifdef __cplusplus
128
129 /**
130 * @brief The default constructor, set all members to zero by default.
131 */
132 aiMetadata() AI_NO_EXCEPT
133 : mNumProperties(0)
134 , mKeys(nullptr)
135 , mValues(nullptr) {
136 // empty
137 }
138
139 aiMetadata( const aiMetadata &rhs )
140 : mNumProperties( rhs.mNumProperties )
141 , mKeys( nullptr )
142 , mValues( nullptr ) {
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( dest: mValues[ i ].mData, src: rhs.mValues[ i ].mData, n: sizeof(bool) );
154 break;
155 case AI_INT32: {
156 int32_t v;
157 ::memcpy( dest: &v, src: rhs.mValues[ i ].mData, n: sizeof( int32_t ) );
158 mValues[ i ].mData = new int32_t( v );
159 }
160 break;
161 case AI_UINT64: {
162 uint64_t v;
163 ::memcpy( dest: &v, src: rhs.mValues[ i ].mData, n: sizeof( uint64_t ) );
164 mValues[ i ].mData = new uint64_t( v );
165 }
166 break;
167 case AI_FLOAT: {
168 float v;
169 ::memcpy( dest: &v, src: rhs.mValues[ i ].mData, n: sizeof( float ) );
170 mValues[ i ].mData = new float( v );
171 }
172 break;
173 case AI_DOUBLE: {
174 double v;
175 ::memcpy( dest: &v, src: rhs.mValues[ i ].mData, n: sizeof( double ) );
176 mValues[ i ].mData = new double( v );
177 }
178 break;
179 case AI_AISTRING: {
180 aiString v;
181 rhs.Get<aiString>( key: mKeys[ i ], value&: v );
182 mValues[ i ].mData = new aiString( v );
183 }
184 break;
185 case AI_AIVECTOR3D: {
186 aiVector3D v;
187 rhs.Get<aiVector3D>( key: mKeys[ i ], value&: 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 }
197
198 }
199 }
200
201 /**
202 * @brief The destructor.
203 */
204 ~aiMetadata() {
205 delete [] mKeys;
206 mKeys = nullptr;
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 }
240
241 // Delete the metadata array
242 delete [] mValues;
243 mValues = nullptr;
244 }
245 }
246
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 nullptr;
255 }
256
257 aiMetadata *data = new aiMetadata;
258 data->mNumProperties = numProperties;
259 data->mKeys = new aiString[ data->mNumProperties ]();
260 data->mValues = new aiMetadataEntry[ data->mNumProperties ]();
261
262 return data;
263 }
264
265 /**
266 * @brief Deallocates property fields + keys.
267 */
268 static inline
269 void Dealloc( aiMetadata *metadata ) {
270 delete metadata;
271 }
272
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];
278
279 for(unsigned int i = 0; i < mNumProperties; ++i)
280 {
281 new_keys[i] = mKeys[i];
282 new_values[i] = mValues[i];
283 }
284
285 delete mKeys;
286 delete mValues;
287
288 mKeys = new_keys;
289 mValues = new_values;
290
291 mNumProperties++;
292
293 Set(mNumProperties - 1, key, value);
294 }
295
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 }
303
304 // Ensure that we have a valid key.
305 if ( key.empty() ) {
306 return false;
307 }
308
309 // Set metadata key
310 mKeys[index] = key;
311
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);
316
317 return true;
318 }
319
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 }
327
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 }
333
334 // Otherwise, output the found value and
335 // return true
336 value = *static_cast<T*>(mValues[index].mData);
337
338 return true;
339 }
340
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 }
352
353 template<typename T>
354 inline
355 bool Get( const std::string& key, T& value ) const {
356 return Get(aiString(key), value);
357 }
358
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 }
369
370 key = &mKeys[index];
371 entry = &mValues[index];
372
373 return true;
374 }
375
376#endif // __cplusplus
377
378};
379
380#endif // AI_METADATA_H_INC
381

source code of qt3d/src/3rdparty/assimp/src/include/assimp/metadata.h