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