1 | /**************************************************************************************** |
2 | |
3 | Copyright (C) 2015 Autodesk, Inc. |
4 | All rights reserved. |
5 | |
6 | Use of this software is subject to the terms of the Autodesk license agreement |
7 | provided at the time of installation or download, or which otherwise accompanies |
8 | this software in either electronic or hard copy form. |
9 | |
10 | ****************************************************************************************/ |
11 | |
12 | /** \file fbxalloc.h |
13 | * Allocation functions definition. |
14 | * |
15 | * It is possible to override memory allocation functions throughout the FBX SDK by |
16 | * providing system memory allocation functions using the handler set functions below. |
17 | * The Microsoft Windows implementation in debug mode allows to specify where the |
18 | * allocations happen by providing the standard block type, file name and line number. |
19 | */ |
20 | #ifndef _FBXSDK_CORE_ARCH_ALLOC_H_ |
21 | #define _FBXSDK_CORE_ARCH_ALLOC_H_ |
22 | |
23 | #include <fbxsdk/fbxsdk_def.h> |
24 | |
25 | #if defined(_DEBUG) && defined(FBXSDK_ENV_WIN) |
26 | #include <crtdbg.h> |
27 | #endif |
28 | |
29 | #if defined(FBXSDK_ENV_MAC) |
30 | #include <malloc/malloc.h> |
31 | #else |
32 | #include <malloc.h> |
33 | #endif |
34 | |
35 | #include <fbxsdk/fbxsdk_nsbegin.h> |
36 | |
37 | #if defined(FBXSDK_CPU_32) && !defined(FBXSDK_ENV_IOS) |
38 | #define FBXSDK_MEMORY_ALIGNMENT ((size_t)8U) |
39 | #else |
40 | #define FBXSDK_MEMORY_ALIGNMENT ((size_t)16U) |
41 | #endif |
42 | |
43 | #define FBXSDK_MEMORY_COPY(dst, src, size) {memcpy(dst,src,size);} |
44 | |
45 | typedef void* (*FbxMallocProc)(size_t); //! Function pointer signature used to replace "malloc" |
46 | typedef void* (*FbxCallocProc)(size_t, size_t); //! Function pointer signature used to replace "calloc" |
47 | typedef void* (*FbxReallocProc)(void*, size_t); //! Function pointer signature used to replace "realloc" |
48 | typedef void (*FbxFreeProc)(void*); //! Function pointer signature used to replace "free" |
49 | |
50 | /** Set the global memory allocation function used internally by the FBX SDK. |
51 | * \param pHandler Function pointer that implements the necessary procedure to allocate memory in the system. */ |
52 | FBXSDK_DLL void FbxSetMallocHandler(FbxMallocProc pHandler); |
53 | |
54 | /** Set the global zero'd memory allocation function used internally by the FBX SDK. |
55 | * \param pHandler Function pointer that implements the necessary procedure to allocate zero'd memory in the system. */ |
56 | FBXSDK_DLL void FbxSetCallocHandler(FbxCallocProc pHandler); |
57 | |
58 | /** Set the global memory re-allocation function used internally by the FBX SDK. |
59 | * \param pHandler Function pointer that implements the necessary procedure to re-allocate memory in the system. */ |
60 | FBXSDK_DLL void FbxSetReallocHandler(FbxReallocProc pHandler); |
61 | |
62 | /** Set the global memory freeing function used internally by the FBX SDK. |
63 | * \param pHandler Function pointer that implements the necessary procedure to free memory in the system. */ |
64 | FBXSDK_DLL void FbxSetFreeHandler(FbxFreeProc pHandler); |
65 | |
66 | /** Get the global memory allocation function used internally by the FBX SDK. |
67 | * \return pHandler Function pointer on FBX's internal malloc */ |
68 | FBXSDK_DLL FbxMallocProc FbxGetMallocHandler(); |
69 | |
70 | /** Get the global zero'd memory allocation function used internally by the FBX SDK. |
71 | * \return pHandler Function pointer on FBX's internal calloc */ |
72 | FBXSDK_DLL FbxCallocProc FbxGetCallocHandler(); |
73 | |
74 | /** Get the global memory re-allocation function used internally by the FBX SDK. |
75 | * \return pHandler Function pointer on FBX's internal realloc */ |
76 | FBXSDK_DLL FbxReallocProc FbxGetReallocHandler(); |
77 | |
78 | /** Get the global memory freeing function used internally by the FBX SDK. |
79 | * \return pHandler Function pointer on FBX's internal free */ |
80 | FBXSDK_DLL FbxFreeProc FbxGetFreeHandler(); |
81 | |
82 | /** Get the default global memory allocation function used internally by the FBX SDK. |
83 | * \return pHandler Function pointer on FBX's internal malloc */ |
84 | FBXSDK_DLL FbxMallocProc FbxGetDefaultMallocHandler(); |
85 | |
86 | /** Get the default global zero'd memory allocation function used internally by the FBX SDK. |
87 | * \return pHandler Function pointer on FBX's internal calloc */ |
88 | FBXSDK_DLL FbxCallocProc FbxGetDefaultCallocHandler(); |
89 | |
90 | /** Get the default global memory re-allocation function used internally by the FBX SDK. |
91 | * \return pHandler Function pointer on FBX's internal realloc */ |
92 | FBXSDK_DLL FbxReallocProc FbxGetDefaultReallocHandler(); |
93 | |
94 | /** Get the default global memory freeing function used internally by the FBX SDK. |
95 | * \return pHandler Function pointer on FBX's internal free */ |
96 | FBXSDK_DLL FbxFreeProc FbxGetDefaultFreeHandler(); |
97 | |
98 | /***************************************************************************************************************************** |
99 | ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! ** |
100 | *****************************************************************************************************************************/ |
101 | #ifndef DOXYGEN_SHOULD_SKIP_THIS |
102 | FBXSDK_DLL void* FbxMalloc(size_t pSize); |
103 | FBXSDK_DLL void* FbxCalloc(size_t pCount, size_t pSize); |
104 | FBXSDK_DLL void* FbxRealloc(void* pData, size_t pSize); |
105 | FBXSDK_DLL void FbxFree(void* pData); |
106 | FBXSDK_DLL char* FbxStrDup(const char* pString); |
107 | FBXSDK_DLL wchar_t* FbxStrDupWC(const wchar_t* pString); |
108 | |
109 | //These versions of allocators use the default system mallocs, and on Windows we also pass the debugging parameters. |
110 | //If you define FBXSDK_ALLOC_DEBUG in your project, the FBX SDK will use these debug versions everywhere. |
111 | FBXSDK_DLL void* FbxMallocDebug(size_t pSize, int pBlock, const char* pFile, int pLine); |
112 | FBXSDK_DLL void* FbxCallocDebug(size_t pCount, size_t pSize, int pBlock, const char* pFile, int pLine); |
113 | FBXSDK_DLL void* FbxReallocDebug(void* pData, size_t pSize, int pBlock, const char* pFile, int pLine); |
114 | FBXSDK_DLL void FbxFreeDebug(void* pData, int pBlock); |
115 | |
116 | //When FBXSDK_ALLOC_DEBUG is defined, redirect allocation calls to the debug version. |
117 | #if defined(FBXSDK_ALLOC_DEBUG) |
118 | #define FbxMalloc(s) FbxMallocDebug(s, _NORMAL_BLOCK, __FILE__, __LINE__) |
119 | #define FbxCalloc(c, s) FbxCallocDebug(c, s, _NORMAL_BLOCK, __FILE__, __LINE__) |
120 | #define FbxRealloc(p, s) FbxReallocDebug(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) |
121 | #define FbxFree(p) FbxFreeDebug(p, _NORMAL_BLOCK) |
122 | #endif |
123 | #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/ |
124 | |
125 | //! Deletion policy for pointer template classes that uses the delete operator. |
126 | template <class Type> class FbxDeletionPolicyDefault |
127 | { |
128 | public: |
129 | //! Destruction policy implementation. |
130 | static inline void DeleteIt(Type** pPtr) |
131 | { |
132 | if( *pPtr ) |
133 | { |
134 | delete *pPtr; |
135 | *pPtr = NULL; |
136 | } |
137 | } |
138 | }; |
139 | |
140 | //! Deletion policy for pointer template classes that uses the FbxDelete() function. |
141 | template<typename T> void FbxDelete(T* p); |
142 | template<typename T> void FbxDelete(const T* p); |
143 | template <class Type> class FbxDeletionPolicyDelete |
144 | { |
145 | public: |
146 | //! Destruction policy implementation. |
147 | static inline void DeleteIt(Type** mPtr) |
148 | { |
149 | if( *mPtr ) |
150 | { |
151 | FbxDelete(*mPtr); |
152 | *mPtr = NULL; |
153 | } |
154 | } |
155 | }; |
156 | |
157 | //! Deletion policy for pointer template classes that uses the FbxFree() function. |
158 | template <class Type> class FbxDeletionPolicyFree |
159 | { |
160 | public: |
161 | //! Destruction policy implementation. |
162 | static inline void DeleteIt(Type** pPtr) |
163 | { |
164 | if( *pPtr ) |
165 | { |
166 | FbxFree(*pPtr); |
167 | *pPtr = NULL; |
168 | } |
169 | } |
170 | }; |
171 | |
172 | //! Deletion policy for pointer template classes that uses the Destroy() function. |
173 | template <class Type> class FbxDeletionPolicyObject |
174 | { |
175 | public: |
176 | //! Destruction policy implementation. |
177 | static inline void DeleteIt(Type** pPtr) |
178 | { |
179 | if( *pPtr ) |
180 | { |
181 | (*pPtr)->Destroy(); |
182 | *pPtr = NULL; |
183 | } |
184 | } |
185 | }; |
186 | |
187 | /** FbxAutoPtr mimics the \c auto_ptr class template implementation available in the C++ Standard Library. The \c auto_ptr template |
188 | * class describes an object that stores a pointer to a single allocated object of type Type* that ensures that the object to which |
189 | * it points gets destroyed automatically when control leaves a scope. */ |
190 | template<class Type, class Policy=FbxDeletionPolicyDefault<Type> > class FbxAutoPtr |
191 | { |
192 | public: |
193 | //! Construct from a pointer. |
194 | explicit FbxAutoPtr(Type* pPtr=0) : mPtr(pPtr){} |
195 | |
196 | //! Destructor. |
197 | ~FbxAutoPtr() { Policy::DeleteIt(&mPtr); } |
198 | |
199 | //! Retrieve the pointer it holds. |
200 | inline Type* Get() const { return mPtr; } |
201 | |
202 | //! Member access operator. |
203 | inline Type* operator->() const { return mPtr; } |
204 | |
205 | //! Convert to a Type pointer. |
206 | inline operator Type* () const { return mPtr; } |
207 | |
208 | //! Dereference operator. |
209 | inline Type& operator*() const { return *mPtr; } |
210 | |
211 | //! Logical not operator. |
212 | inline bool operator!() const { return mPtr == 0; } |
213 | |
214 | //! Convert to boolean value. |
215 | inline operator bool () const { return mPtr != 0; } |
216 | |
217 | //! Reset the scoped pointer by swapping with another pointer. |
218 | inline void Reset(Type* pPtr=0) |
219 | { |
220 | FBX_ASSERT(pPtr == 0 || pPtr != mPtr); //Catch self-reset errors |
221 | FbxAutoPtr<Type, Policy>(pPtr).Swap(*this); |
222 | } |
223 | |
224 | //! Swap with another pointer. |
225 | inline void Swap(FbxAutoPtr& pOther) |
226 | { |
227 | Type* TmpPtr = pOther.mPtr; |
228 | pOther.mPtr = mPtr; |
229 | mPtr = TmpPtr; |
230 | } |
231 | |
232 | //! Release the pointer, so that it won't perform deletion in its destruction. |
233 | inline Type* Release() |
234 | { |
235 | Type* TmpPtr = mPtr; |
236 | mPtr = NULL; |
237 | return TmpPtr; |
238 | } |
239 | |
240 | /***************************************************************************************************************************** |
241 | ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! ** |
242 | *****************************************************************************************************************************/ |
243 | #ifndef DOXYGEN_SHOULD_SKIP_THIS |
244 | private: |
245 | FbxAutoPtr(const FbxAutoPtr&); |
246 | FbxAutoPtr& operator=(const FbxAutoPtr&); |
247 | |
248 | Type* mPtr; |
249 | #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/ |
250 | }; |
251 | |
252 | //! Scoped pointer for FbxMalloc allocations, which call FbxFree() to deallocate. |
253 | template <class Type> class FbxAutoFreePtr : public FbxAutoPtr<Type, FbxDeletionPolicyFree<Type> > |
254 | { |
255 | public: |
256 | //! Construct from a pointer. |
257 | explicit FbxAutoFreePtr(Type* pPtr=0) : FbxAutoPtr<Type, FbxDeletionPolicyFree<Type> >(pPtr){} |
258 | }; |
259 | |
260 | //! Scoped pointer for FbxNew allocations, which call FbxDelete() to deallocate. |
261 | template <class Type> class FbxAutoDeletePtr : public FbxAutoPtr<Type, FbxDeletionPolicyDelete<Type> > |
262 | { |
263 | public: |
264 | //! Construct from a pointer. |
265 | explicit FbxAutoDeletePtr(Type* pPtr=0) : FbxAutoPtr<Type, FbxDeletionPolicyDelete<Type> >(pPtr){} |
266 | }; |
267 | |
268 | //! Scoped pointer for FbxObject derived classes, which call Destroy() to deallocate. |
269 | template <class Type> class FbxAutoDestroyPtr : public FbxAutoPtr<Type, FbxDeletionPolicyObject<Type> > |
270 | { |
271 | public: |
272 | //! Construct from a pointer. |
273 | explicit FbxAutoDestroyPtr(Type* pPtr=0) : FbxAutoPtr<Type, FbxDeletionPolicyObject<Type> >(pPtr){} |
274 | }; |
275 | |
276 | |
277 | /** FbxSharedPtr class describes an object that stores a pointer to a single allocated object of type |
278 | * Type* that ensures that the object to which it points gets destroyed automatically when the control |
279 | * leaves a scope and the reference count is 0. */ |
280 | class RefCount |
281 | { |
282 | public: |
283 | RefCount() { Init(); }; |
284 | ~RefCount() { Init(); }; |
285 | |
286 | void Init() { count = 0; } |
287 | void IncRef() { count++; } |
288 | int DecRef() { count--; if (count < 0) count = 0; return count; } |
289 | |
290 | private: |
291 | int count; |
292 | }; |
293 | |
294 | template<class Type, class Policy=FbxDeletionPolicyDefault<Type> > class FbxSharedPtr |
295 | { |
296 | public: |
297 | // Default constructor. |
298 | FbxSharedPtr() : |
299 | mPtr(0), |
300 | mRef(0) |
301 | {} |
302 | |
303 | //! Construct from a pointer. |
304 | explicit FbxSharedPtr(Type* pPtr) : |
305 | mPtr(pPtr), |
306 | mRef(0) |
307 | { |
308 | if (pPtr != 0) |
309 | { |
310 | mRef = (RefCount*)FbxMalloc(sizeof(RefCount)); |
311 | mRef->Init(); |
312 | mRef->IncRef(); |
313 | } |
314 | } |
315 | |
316 | //! Copy constructor |
317 | FbxSharedPtr(const FbxSharedPtr& pSPtr) : |
318 | mPtr(pSPtr.mPtr), |
319 | mRef(pSPtr.mRef) |
320 | { |
321 | if (pSPtr.mPtr != 0 && mRef != 0) |
322 | mRef->IncRef(); |
323 | } |
324 | |
325 | // Assignment operator |
326 | FbxSharedPtr& operator=(const FbxSharedPtr& pSPtr) |
327 | { |
328 | if (this != &pSPtr) // avoid self assignment |
329 | { |
330 | Reset(); |
331 | |
332 | if (pSPtr.mPtr) |
333 | { |
334 | mPtr = pSPtr.mPtr; |
335 | mRef = pSPtr.mRef; |
336 | FBX_ASSERT(mRef != NULL); |
337 | mRef->IncRef(); |
338 | } |
339 | } |
340 | return *this; |
341 | } |
342 | |
343 | //! Destructor. |
344 | ~FbxSharedPtr() { Destroy(); } |
345 | |
346 | void Destroy() { Reset(); } |
347 | |
348 | //! Retrieve the pointer it holds. |
349 | inline Type* Get() const { return mPtr; } |
350 | |
351 | //! Member access operator. |
352 | inline Type* operator->() const { return mPtr; } |
353 | |
354 | //! Convert to a Type pointer. |
355 | inline operator Type* () const { return mPtr; } |
356 | |
357 | //! Dereference operator. |
358 | inline Type& operator*() const { return *mPtr; } |
359 | |
360 | //! Logical not operator. |
361 | inline bool operator!() const { return mPtr == 0; } |
362 | |
363 | //! Convert to boolean value. |
364 | inline operator bool () const { return mPtr != 0; } |
365 | |
366 | |
367 | /***************************************************************************************************************************** |
368 | ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! ** |
369 | *****************************************************************************************************************************/ |
370 | #ifndef DOXYGEN_SHOULD_SKIP_THIS |
371 | private: |
372 | void Reset() |
373 | { |
374 | if (mRef) |
375 | { |
376 | FBX_ASSERT(mPtr != 0); |
377 | if (mRef->DecRef() == 0) |
378 | { |
379 | Policy::DeleteIt(&mPtr); |
380 | FbxFree(mRef); |
381 | mRef = NULL; |
382 | } |
383 | } |
384 | } |
385 | |
386 | Type* mPtr; |
387 | RefCount* mRef; |
388 | #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/ |
389 | }; |
390 | |
391 | //! Scoped pointer for FbxMalloc allocations, which call FbxFree() to deallocate. |
392 | template <class Type> class FbxSharedFreePtr : public FbxSharedPtr<Type, FbxDeletionPolicyFree<Type> > |
393 | { |
394 | public: |
395 | //! Construct from a pointer. |
396 | explicit FbxSharedFreePtr(Type* pPtr=0) : FbxSharedPtr<Type, FbxDeletionPolicyFree<Type> >(pPtr){} |
397 | }; |
398 | |
399 | //! Scoped pointer for FbxNew allocations, which call FbxDelete() to deallocate. |
400 | template <class Type> class FbxSharedDeletePtr : public FbxSharedPtr<Type, FbxDeletionPolicyDelete<Type> > |
401 | { |
402 | public: |
403 | //! Construct from a pointer. |
404 | explicit FbxSharedDeletePtr(Type* pPtr=0) : FbxSharedPtr<Type, FbxDeletionPolicyDelete<Type> >(pPtr){} |
405 | }; |
406 | |
407 | //! Scoped pointer for FbxObject derived classes, which call Destroy() to deallocate. |
408 | template <class Type> class FbxSharedDestroyPtr : public FbxSharedPtr<Type, FbxDeletionPolicyObject<Type> > |
409 | { |
410 | public: |
411 | //! Construct from a pointer. |
412 | explicit FbxSharedDestroyPtr(Type* pPtr=0) : FbxSharedPtr<Type, FbxDeletionPolicyObject<Type> >(pPtr){} |
413 | }; |
414 | |
415 | |
416 | |
417 | #include <fbxsdk/fbxsdk_nsend.h> |
418 | |
419 | #endif /* _FBXSDK_CORE_ARCH_ALLOC_H_ */ |
420 | |