fbxarray.h

Go to the documentation of this file.
00001 /****************************************************************************************
00002  
00003    Copyright (C) 2012 Autodesk, Inc.
00004    All rights reserved.
00005  
00006    Use of this software is subject to the terms of the Autodesk license agreement
00007    provided at the time of installation or download, or which otherwise accompanies
00008    this software in either electronic or hard copy form.
00009  
00010 ****************************************************************************************/
00011 
00013 #ifndef _FBXSDK_CORE_BASE_ARRAY_H_
00014 #define _FBXSDK_CORE_BASE_ARRAY_H_
00015 
00016 #include <fbxsdk/fbxsdk_def.h>
00017 
00018 #include <fbxsdk/fbxsdk_nsbegin.h>
00019 
00020 #define FBXSDK_ARRAY_BLOCKSIZE 4
00021 
00022 template <size_t TypeSize> class FbxArrayBase
00023 {
00024 public:
00028     inline int GetCount() const { return GetArrayCount(); }
00029 
00031     inline void Clear()
00032     {
00033         if (mBaseArray!=NULL)
00034         {
00035             FbxFree(mBaseArray);
00036             mArrayCount = 0;
00037             mBaseArray = NULL;
00038         }
00039     }
00040 
00041 
00043     inline void Empty()
00044     {
00045     #ifdef _DEBUG
00046         memset( mBaseArray+ GetHeaderOffset() ,0,GetArrayCount()*TypeSize);
00047     #endif
00048         SetArrayCount(0);
00049     }
00050 
00051 
00057     inline int Reserve(int pCapacity)
00058     {
00059         FBX_ASSERT( pCapacity > 0 );
00060 
00061         if( pCapacity )
00062         {
00063             const FbxUInt lTempNewBlockCount = ( (FbxUInt) (pCapacity + FBXSDK_ARRAY_BLOCKSIZE - 1 ) / FBXSDK_ARRAY_BLOCKSIZE );
00064             const FbxUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00065 
00066             int lArrayCount = GetArrayCount();
00067             int lBlockCount = GetBlockCount();
00068 
00069             const FbxUInt lOldArraySize = lArrayCount*TypeSize;
00070             const FbxUInt lNewArraySize = lNewBlockCount*FBXSDK_ARRAY_BLOCKSIZE*TypeSize;
00071 
00072             if (lNewBlockCount != (FbxUInt) lBlockCount)
00073             {
00074                 char* lBaseArray = (char*)FbxRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00075                 if (!lBaseArray)
00076                     return GetBlockCount()*FBXSDK_ARRAY_BLOCKSIZE;
00077                 mBaseArray = lBaseArray;
00078             }
00079 
00080             if( lNewBlockCount > (FbxUInt) lBlockCount ) {
00081                 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00082                 SetArrayCount(lArrayCount);
00083             } else if (pCapacity < lArrayCount)
00084             {
00085                 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pCapacity*TypeSize, 0, (size_t) (lNewArraySize-pCapacity*TypeSize) );
00086                 SetArrayCount(pCapacity);
00087             }
00088 
00089             SetBlockCount(lNewBlockCount);
00090         }
00091 
00092         return GetBlockCount()*FBXSDK_ARRAY_BLOCKSIZE;
00093     }
00094 
00095 
00097     //  Differ from SetCount because array capacity can be lowered.
00098 
00104     inline void SetCount (int pCount)
00105     {
00106     #ifdef _DEBUG
00107         if (pCount<0)
00108         {
00109             FBX_ASSERT_NOW ("ArrayUL : Item count can't be negative");
00110             return ;
00111         }
00112     #endif
00113         int lArrayCount = GetArrayCount();
00114         if (pCount > lArrayCount)
00115         {
00116             AddMultiple( pCount-lArrayCount);
00117         } 
00118         else
00119         {
00120             SetArrayCount(pCount);
00121         }
00122     }
00123 
00124     inline void Resize(int pItemCount)
00125     {
00126         FBX_ASSERT( pItemCount >= 0 );
00127 
00128         const FbxUInt lTempNewBlockCount = ( (FbxUInt) (pItemCount + FBXSDK_ARRAY_BLOCKSIZE - 1 ) / FBXSDK_ARRAY_BLOCKSIZE );
00129         const FbxUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00130 
00131         int lArrayCount = GetArrayCount();
00132         int lBlockCount = GetBlockCount();
00133 
00134         const FbxUInt lOldArraySize = lArrayCount*TypeSize;
00135         const FbxUInt lNewArraySize = lNewBlockCount*FBXSDK_ARRAY_BLOCKSIZE*TypeSize;
00136 
00137         if (lNewBlockCount != (FbxUInt) lBlockCount)
00138         {
00139             char* lBaseArray = (char*)FbxRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00140             if (!lBaseArray)
00141                 return;
00142             mBaseArray = lBaseArray;
00143         }
00144 
00145         if( lNewBlockCount > (FbxUInt) lBlockCount )
00146         {
00147             memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00148         }
00149         else if (pItemCount < lArrayCount)
00150         {
00151             memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pItemCount*TypeSize, 0, (size_t) (lNewArraySize-pItemCount*TypeSize) );
00152         }
00153 
00154         SetBlockCount(lNewBlockCount);
00155         SetArrayCount(pItemCount);
00156     }
00157 
00158     inline void AddMultiple(int pItemCount)
00159     {
00160         FBX_ASSERT( pItemCount > 0 );
00161 
00162         if( pItemCount )
00163         {
00164             int lArrayCount = GetArrayCount();
00165             int lBlockCount = GetBlockCount();
00166             const FbxUInt lTempNewBlockCount = ( (FbxUInt) (lArrayCount+pItemCount + FBXSDK_ARRAY_BLOCKSIZE - 1 ) / FBXSDK_ARRAY_BLOCKSIZE );
00167             const FbxUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00168 
00169             const FbxUInt lOldArraySize = lArrayCount*TypeSize;
00170             const FbxUInt lNewArraySize = lNewBlockCount*FBXSDK_ARRAY_BLOCKSIZE*TypeSize;
00171 
00172             FBX_ASSERT( lOldArraySize < lNewArraySize );
00173 
00174             if( lNewBlockCount > (FbxUInt) lBlockCount )
00175             {
00176                 char* lBaseArray = (char*)FbxRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00177                 if (!lBaseArray)
00178                     return;
00179                 mBaseArray = lBaseArray;
00180                 lBlockCount = lNewBlockCount;
00181             }
00182 
00183             memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00184             SetArrayCount ( lArrayCount + pItemCount );
00185             SetBlockCount (lBlockCount);
00186         }
00187     }
00188 
00190 //
00191 //  WARNING!
00192 //
00193 //  Anything beyond these lines may not be documented accurately and is
00194 //  subject to change without notice.
00195 //
00197 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00198 protected:
00199     struct Header {
00200         int mBlockCount;
00201     };
00202 
00204     inline FbxArrayBase() : mArrayCount(0), mBaseArray(NULL)
00205     {
00206     }
00207 
00209     inline ~FbxArrayBase(){
00210         Clear ();
00211     }
00212 
00220     inline int InsertAt(int pIndex, void *pItem)
00221     {
00222         int lArrayCount = GetArrayCount();
00223         int lBlockCount = GetBlockCount();
00224 
00225         FBX_ASSERT( pIndex >= 0 );
00226 
00227         if (pIndex>lArrayCount) {
00228             pIndex = GetArrayCount();
00229         }
00230 
00231         if (lArrayCount>= lBlockCount*FBXSDK_ARRAY_BLOCKSIZE)
00232         {
00233             // must Alloc.Realloc some new space
00234 
00235             // double the number of blocks.
00236             lBlockCount = ( 0 == lBlockCount ) ? 1 : lBlockCount * 2;
00237             char* lBaseArray = (char*)FbxRealloc(mBaseArray, (size_t) (lBlockCount*FBXSDK_ARRAY_BLOCKSIZE*TypeSize) + GetHeaderOffset() );
00238             if(!lBaseArray)
00239                 return -1;
00240             mBaseArray = lBaseArray;
00241         }
00242 
00243         if (pIndex<lArrayCount)
00244         {
00245             // This is an insert
00246             memmove (&(mBaseArray[(pIndex+1)*TypeSize+ GetHeaderOffset() ]), &(mBaseArray[(pIndex)*TypeSize+ GetHeaderOffset()] ), TypeSize*(lArrayCount-pIndex));
00247         }
00248 
00249         memmove (&(mBaseArray[(pIndex)*TypeSize+ GetHeaderOffset() ]), pItem, TypeSize);
00250 
00251         SetArrayCount(lArrayCount+1);
00252         SetBlockCount(lBlockCount);
00253 
00254         return pIndex;
00255     }
00256 
00257 
00264     inline void* GetAt(int pIndex) { return &(mBaseArray[(pIndex)*TypeSize+ GetHeaderOffset() ]); }
00265 
00272     inline void RemoveAt(int pIndex)
00273     {
00274 
00275     #if defined(_DEBUG) && !defined(FBXSDK_ENV_MAC)
00276         if (!ValidateIndex( pIndex ))
00277         {
00278             return;
00279         }
00280     #endif
00281         int lArrayCount = GetArrayCount();
00282         if (pIndex+1<lArrayCount)
00283         {
00284             memmove (&(mBaseArray[(pIndex)*TypeSize+ GetHeaderOffset() ]), &(mBaseArray[(pIndex+1)*TypeSize+ GetHeaderOffset() ]), TypeSize*(lArrayCount-pIndex-1));
00285         }
00286 
00287         SetArrayCount( lArrayCount-1 );
00288 
00289     #ifdef _DEBUG
00290         memset( &(mBaseArray[(GetArrayCount())*TypeSize+ GetHeaderOffset() ]),0,TypeSize);
00291     #endif
00292     }
00293 
00294 
00300     inline bool ValidateIndex( int pIndex ) const
00301     {
00302         int lArrayCount = GetArrayCount();
00303         if (pIndex>=0 && pIndex<lArrayCount)
00304         {
00305             return true;
00306         } 
00307         else
00308         {
00309             FBX_ASSERT_NOW("Array : Index out of range");
00310             return false;
00311         }
00312     }
00313 
00314     inline Header* const GetHeader() const
00315     {
00316         return (Header* const)mBaseArray;
00317     }
00318     inline Header* GetHeader()
00319     {
00320         return (Header*)mBaseArray;
00321     }
00322     inline int GetHeaderOffset() const
00323     {
00324         return sizeof(Header);
00325     }
00326     inline int GetArrayCount() const
00327     {
00328         return mArrayCount;
00329     }
00330     inline void SetArrayCount(int pArrayCount)
00331     {
00332         mArrayCount = pArrayCount;
00333     }
00334     inline int GetBlockCount() const
00335     {
00336         return GetHeader() ? GetHeader()->mBlockCount : 0;
00337     }
00338     inline void SetBlockCount(int pArrayCount)
00339     {
00340         if (GetHeader()) GetHeader()->mBlockCount = pArrayCount;
00341     }
00342 
00343     int     mArrayCount;
00344     char*   mBaseArray;
00345 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00346 };
00347 
00351 template <class Type> class FbxArray : public FbxArrayBase<sizeof(Type)>
00352 {
00353     typedef FbxArrayBase<sizeof(Type)> ParentClass;
00354 
00355 #if defined(FBXSDK_COMPILER_MSC)
00356     // Previously class FbxArray is for pointers. Somehow, it's used to store other types.
00357     // Here's a compile-time checking for known incompatible classes.
00358     // If it happens you find new incompatible ones, declare them with macro FBXSDK_INCOMPATIBLE_WITH_ARRAY
00359     // Also see file string.h
00360     FBX_ASSERT_STATIC(FBXSDK_IS_SIMPLE_TYPE(Type) || __is_enum(Type) || (__has_trivial_constructor(Type)&&__has_trivial_destructor(Type)) || !FBXSDK_IS_INCOMPATIBLE_WITH_ARRAY(Type));
00361 #endif
00362 
00363 public:
00365     FbxArray() : ParentClass() {}
00366 
00368     FbxArray(const FbxArray& pArrayTemplate) : ParentClass()
00369     {
00370         *this = pArrayTemplate;
00371     }
00372 
00374     ~FbxArray() {}
00375 
00382     inline int InsertAt(int pIndex, Type pItem)
00383     {
00384         return ParentClass::InsertAt( pIndex,&pItem );
00385     }
00386 
00392     inline Type RemoveAt(int pIndex)
00393     {
00394         Type tmpItem = GetAt(pIndex);
00395         ParentClass::RemoveAt( pIndex );
00396         return tmpItem;
00397     }
00398 
00403     inline Type RemoveLast()
00404     {
00405         return RemoveAt(ParentClass::GetArrayCount()-1);
00406     }
00407 
00412     inline bool RemoveIt(Type pItem)
00413     {
00414         int Index = Find (pItem);
00415         if (Index>=0)
00416         {
00417             RemoveAt (Index);
00418             return true;
00419         }
00420         return false;
00421     }
00422 
00428     inline Type &operator[](int pIndex) const
00429     {
00430     #if defined(_DEBUG) && !defined(FBXSDK_ENV_MAC)
00431         if (!ParentClass::ValidateIndex( pIndex ))
00432         {
00433             return (Type&)(ParentClass::mBaseArray[(0)*sizeof(Type)+ ParentClass::GetHeaderOffset()]);
00434         }
00435     #endif
00436         return (Type&)(ParentClass::mBaseArray[(pIndex)*sizeof(Type)+ ParentClass::GetHeaderOffset()]);
00437     }
00438 
00444     inline void SetAt(int pIndex, Type pItem)
00445     {
00446     #if defined(_DEBUG) && !defined(FBXSDK_ENV_MAC)
00447         if (!ParentClass::ValidateIndex( pIndex ))
00448         {
00449             return;
00450         }
00451     #endif
00452         GetArray()[pIndex] = pItem;
00453     }
00454 
00459     inline void SetLast(Type pItem)
00460     {
00461         SetAt (ParentClass::GetArrayCount()-1, pItem);
00462     }
00463 
00469     inline Type GetAt(int pIndex) const
00470     {
00471     #if defined(_DEBUG) && !defined(FBXSDK_ENV_MAC)
00472         if (!ParentClass::ValidateIndex( pIndex ))
00473         {
00474             return (Type&)(ParentClass::mBaseArray[(0)*sizeof(Type)+ ParentClass::GetHeaderOffset()]);
00475         }
00476     #endif
00477         return (Type&)(ParentClass::mBaseArray[(pIndex)*sizeof(Type)+ ParentClass::GetHeaderOffset()]);
00478     }
00479 
00484     inline Type GetFirst() const
00485     {
00486         FBX_ASSERT( ParentClass::GetArrayCount() >= 1 );
00487         return GetAt(0);
00488     }
00489 
00494     inline Type GetLast() const
00495     {
00496         FBX_ASSERT( ParentClass::GetArrayCount() >= 1 );
00497         return GetAt(ParentClass::GetArrayCount()-1);
00498     }
00499 
00504     inline int Find(Type pItem) const
00505     {
00506         return FindAfter( -1, pItem );
00507     }
00508 
00515     inline int FindAfter(int pAfterIndex, Type pItem) const
00516     {
00517     #ifdef _DEBUG
00518         if ( pAfterIndex > ParentClass::GetArrayCount() || pAfterIndex < -1 )
00519         {
00520             FBX_ASSERT_NOW ("ArrayUL : Search Begin Index out of range");
00521             return -1;
00522         }
00523     #endif
00524         int Count;
00525         for ( Count=pAfterIndex+1; Count<ParentClass::GetArrayCount(); Count++)
00526         {
00527             if (GetAt(Count)==pItem)
00528             {
00529                 return Count;
00530             }
00531         }
00532         return -1;
00533     }
00534 
00541     inline int FindBefore(int pBeforeIndex, Type pItem) const
00542     {
00543     #ifdef _DEBUG
00544         if ( pBeforeIndex > ParentClass::GetArrayCount() || pBeforeIndex <= 0 )
00545         {
00546             FBX_ASSERT_NOW ("ArrayUL : Search Begin Index out of range");
00547             return -1;
00548         }
00549     #endif
00550         int Count;
00551         for ( Count=pBeforeIndex-1; Count>=0; Count--)
00552         {
00553             if (GetAt(Count)==pItem)
00554             {
00555                 return Count;
00556             }
00557         }
00558         return -1;
00559     }
00560 
00565     inline int Add(Type pItem)
00566     {
00567         return InsertAt(ParentClass::GetArrayCount(), pItem);
00568     }
00569 
00574     inline int AddUnique(Type pItem)
00575     {
00576         int lReturnIndex = Find(pItem);
00577         if (lReturnIndex == -1)
00578         {
00579             lReturnIndex = Add(pItem);
00580         }
00581         return lReturnIndex;
00582     }
00583 
00587     inline void AddMultiple(FbxUInt pItemCount)
00588     {
00589         ParentClass::AddMultiple(pItemCount);
00590     }
00591 
00595     inline void AddArray(const FbxArray<Type> &pArray)
00596     {
00597         int lSourceIndex, lCount = pArray.GetCount();
00598         if( lCount == 0 ) return;
00599         int lDestinationIndex = ParentClass::GetCount();
00600         AddMultiple(lCount);
00601         for( lSourceIndex = 0; lSourceIndex < lCount; lSourceIndex++)
00602         {
00603             SetAt(lDestinationIndex++, pArray[lSourceIndex]);
00604         }
00605     }
00606 
00610     inline void AddArrayNoDuplicate(const FbxArray<Type> &pArray)
00611     {
00612         int i, lCount = pArray.GetCount();
00613         for( i = 0; i < lCount; i++)
00614         {
00615             Type lItem = pArray[i];
00616             if (Find(lItem) == -1)
00617             {
00618                 Add(lItem);
00619             }
00620         }
00621     }
00622 
00626     inline void RemoveArray(const FbxArray<Type> &pArray)
00627     {
00628         int lRemoveIndex, lRemoveCount = pArray.GetCount();
00629         for( lRemoveIndex = 0; lRemoveIndex < lRemoveCount; lRemoveIndex++)
00630         {
00631             RemoveIt(pArray[lRemoveIndex]);
00632         }
00633     }
00634 
00636     inline Type* GetArray() const
00637     {
00638         if (ParentClass::mBaseArray == NULL)
00639             return NULL;
00640 
00641         return (Type*)(ParentClass::mBaseArray+ ParentClass::GetHeaderOffset()) ;
00642     }
00643 
00645     inline FbxArray<Type>& operator=(const FbxArray<Type>& pArrayTemplate)
00646     {
00647         if ( this != &pArrayTemplate )
00648         {
00649             ParentClass::Clear();
00650 
00651             int i, lCount = pArrayTemplate.GetCount();
00652 
00653             for (i = 0; i < lCount; i++)
00654             {
00655                 Add(pArrayTemplate[i]);
00656             }
00657         }
00658 
00659         return (*this);
00660     }
00661 
00663     inline operator Type* ()
00664     {
00665         return GetArray();
00666     }
00667 };
00668 
00669 template <class Type> inline void FbxArrayDelete(FbxArray<Type>& Array)
00670 {
00671     FbxUInt lItemCount = Array.GetCount();
00672     while( lItemCount )
00673     {
00674         lItemCount--;
00675         Type& Item = (Array.operator[](lItemCount));
00676         FbxDelete(Item);
00677         Item = NULL;
00678     }
00679     Array.Clear();
00680 }
00681 
00683 //
00684 //  WARNING!
00685 //
00686 //  Anything beyond these lines may not be documented accurately and is
00687 //  subject to change without notice.
00688 //
00690 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00691     class FbxArrayBase_Size
00692     {
00693     public:
00694         FbxArrayBase_Size(int pItemSize) : mItemSize(pItemSize) {}
00695         inline int GetTypeSize() const { return mItemSize; }
00696 
00697     private:
00698         int mItemSize;
00699     };
00700 
00705     template <class TypeSize> class FbxArrayBase_
00706     {
00707     protected:
00708         struct Header
00709         {
00710             int mArrayCount;
00711             int mBlockCount;
00712         };
00713 
00717         inline FbxArrayBase_(TypeSize pTypeSize) : mTypeSize(pTypeSize)
00718         {
00719             mBaseArray = NULL;
00720         }
00721 
00723         inline ~FbxArrayBase_()
00724         {
00725             Clear();
00726         }
00727 
00728         inline int GetTypeSize() const { return mTypeSize.GetTypeSize(); }
00729 
00733         inline int GetCount() const { return GetArrayCount(); }
00734 
00738         inline void Clear()
00739         {
00740             if (mBaseArray!=NULL)
00741             {
00742                 FbxFree(mBaseArray);
00743                 mBaseArray = NULL;
00744             }
00745         }
00746 
00750         inline void Empty()
00751         {
00752         #ifdef _DEBUG
00753             memset(mBaseArray+ GetHeaderOffset(), 0, GetArrayCount()*GetTypeSize());
00754         #endif
00755             SetArrayCount(0);
00756         }
00757 
00763         inline int Reserve(int pCapacity)
00764         {
00765             FBX_ASSERT( pCapacity > 0 );
00766             if( pCapacity )
00767             {
00768                 const FbxUInt lTempNewBlockCount = ( (FbxUInt) (pCapacity + FBXSDK_ARRAY_BLOCKSIZE - 1 ) / FBXSDK_ARRAY_BLOCKSIZE );
00769                 const FbxUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00770 
00771                 int lArrayCount = GetArrayCount();
00772                 int lBlockCount = GetBlockCount();
00773 
00774                 const FbxUInt lOldArraySize = lArrayCount*GetTypeSize();
00775                 const FbxUInt lNewArraySize = lNewBlockCount*FBXSDK_ARRAY_BLOCKSIZE*GetTypeSize();
00776 
00777                 if (lNewBlockCount != (FbxUInt) lBlockCount)
00778                 {
00779                     char* lBaseArray = (char*)FbxRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00780                     if (!lBaseArray)
00781                         return GetBlockCount()*FBXSDK_ARRAY_BLOCKSIZE;
00782                     mBaseArray = lBaseArray;
00783                 }
00784 
00785                 if( lNewBlockCount > (FbxUInt) lBlockCount ) {
00786                     memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00787                     SetArrayCount(lArrayCount);
00788                 } 
00789                 else if (pCapacity < lArrayCount)
00790                 {
00791                     memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pCapacity*GetTypeSize(), 0, (size_t) (lNewArraySize-pCapacity*GetTypeSize()) );
00792                     SetArrayCount(pCapacity);
00793                 }
00794 
00795                 SetBlockCount(lNewBlockCount);
00796             }
00797 
00798             return GetBlockCount()*FBXSDK_ARRAY_BLOCKSIZE;
00799         }
00800 
00807         inline void SetCount(int pCount)
00808         {
00809         #ifdef _DEBUG
00810             if (pCount<0)
00811             {
00812                 FBX_ASSERT_NOW ("ArrayUL : Item count can't be negative");
00813                 return ;
00814             }
00815         #endif
00816             int lArrayCount = GetArrayCount();
00817             if (pCount > lArrayCount)
00818             {
00819                 AddMultiple( pCount-lArrayCount);
00820             } 
00821             else
00822             {
00823                 SetArrayCount(pCount);
00824             }
00825         }
00826 
00833         inline void Resize(int pItemCount)
00834         {
00835             FBX_ASSERT( pItemCount >= 0 );
00836 
00837             const FbxUInt lTempNewBlockCount = ( (FbxUInt) (pItemCount + FBXSDK_ARRAY_BLOCKSIZE - 1 ) / FBXSDK_ARRAY_BLOCKSIZE );
00838             const FbxUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00839 
00840             int lArrayCount = GetArrayCount();
00841             int lBlockCount = GetBlockCount();
00842 
00843             const FbxUInt lOldArraySize = lArrayCount*GetTypeSize();
00844             const FbxUInt lNewArraySize = lNewBlockCount*FBXSDK_ARRAY_BLOCKSIZE*GetTypeSize();
00845 
00846             if (lNewBlockCount != (FbxUInt) lBlockCount)
00847             {
00848                 char* lBaseArray = (char*)FbxRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00849                 if (!lBaseArray)
00850                     return;
00851                 mBaseArray = lBaseArray;
00852             }
00853 
00854             if( lNewBlockCount > (FbxUInt) lBlockCount )
00855             {
00856                 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00857             }
00858             else if (pItemCount < lArrayCount)
00859             {
00860                 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pItemCount*GetTypeSize(), 0, (size_t) (lNewArraySize-pItemCount*GetTypeSize()) );
00861             }
00862 
00863             SetBlockCount(lNewBlockCount);
00864             SetArrayCount(pItemCount);
00865         }
00866 
00873         inline void AddMultiple(int pItemCount)
00874         {
00875             FBX_ASSERT( pItemCount > 0 );
00876             if( pItemCount )
00877             {
00878                 int lArrayCount = GetArrayCount();
00879                 int lBlockCount = GetBlockCount();
00880                 const FbxUInt lTempNewBlockCount = ( (FbxUInt) (lArrayCount+pItemCount + FBXSDK_ARRAY_BLOCKSIZE - 1 ) / FBXSDK_ARRAY_BLOCKSIZE );
00881                 const FbxUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00882 
00883                 const FbxUInt lOldArraySize = lArrayCount*GetTypeSize();
00884                 const FbxUInt lNewArraySize = lNewBlockCount*FBXSDK_ARRAY_BLOCKSIZE*GetTypeSize();
00885 
00886                 FBX_ASSERT( lOldArraySize < lNewArraySize );
00887 
00888                 if( lNewBlockCount > (FbxUInt) lBlockCount )
00889                 {
00890                     char* lBaseArray = (char*)FbxRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00891                     if (!lBaseArray)
00892                         return;
00893                     mBaseArray = lBaseArray;
00894                     lBlockCount = lNewBlockCount;
00895                 }
00896 
00897                 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00898                 SetArrayCount ( lArrayCount + pItemCount );
00899                 SetBlockCount (lBlockCount);
00900             }
00901         }
00902 
00910         inline int InsertAt(int pIndex, void* pItem)
00911         {
00912             int lArrayCount = GetArrayCount();
00913             int lBlockCount = GetBlockCount();
00914 
00915             FBX_ASSERT( pIndex >= 0 );
00916 
00917             if (pIndex>lArrayCount) {
00918                 pIndex = GetArrayCount();
00919             }
00920 
00921             if (lArrayCount>= lBlockCount*FBXSDK_ARRAY_BLOCKSIZE)
00922             {
00923                 // must Alloc.Realloc some new space
00924 
00925                 // double the number of blocks.
00926                 lBlockCount = ( 0 == lBlockCount ) ? 1 : lBlockCount * 2;
00927                 char* lBaseArray = (char*)FbxRealloc(mBaseArray, (size_t) (lBlockCount*FBXSDK_ARRAY_BLOCKSIZE*GetTypeSize()) + GetHeaderOffset() );
00928                 if(!lBaseArray)
00929                     return -1;
00930                 mBaseArray = lBaseArray;
00931             }
00932 
00933             if (pIndex<lArrayCount)
00934             {
00935                 // This is an insert
00936                 memmove (&(mBaseArray[(pIndex+1)*GetTypeSize()+ GetHeaderOffset() ]), &(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset()] ), GetTypeSize()*(lArrayCount-pIndex));
00937             }
00938 
00939             memmove (&(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]), pItem, GetTypeSize());
00940 
00941             SetArrayCount(lArrayCount+1);
00942             SetBlockCount(lBlockCount);
00943 
00944             return pIndex;
00945         }
00946 
00947 
00954         inline void* GetAt(int pIndex) { return &(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset()]); }
00955 
00962         inline void RemoveAt(int pIndex)
00963         {
00964         #if defined(_DEBUG) && !defined(FBXSDK_ENV_MAC)
00965             if (!ValidateIndex( pIndex ))
00966             {
00967                 return;
00968             }
00969         #endif
00970             int lArrayCount = GetArrayCount();
00971             if (pIndex+1<lArrayCount)
00972             {
00973                 memmove (&(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]), &(mBaseArray[(pIndex+1)*GetTypeSize()+ GetHeaderOffset() ]), GetTypeSize()*(lArrayCount-pIndex-1));
00974             }
00975 
00976             SetArrayCount( lArrayCount-1 );
00977 
00978         #ifdef _DEBUG
00979             memset( &(mBaseArray[(GetArrayCount())*GetTypeSize()+ GetHeaderOffset() ]),0,GetTypeSize());
00980         #endif
00981         }
00982 
00988         inline bool ValidateIndex( int pIndex ) const
00989         {
00990             int lArrayCount = GetArrayCount();
00991             if (pIndex>=0 && pIndex<lArrayCount)
00992             {
00993                 return true;
00994             }
00995             else
00996             {
00997                 FBX_ASSERT_NOW("Array : Index out of range");
00998                 return false;
00999             }
01000         }
01001 
01002         inline const Header* GetHeader() const
01003         {
01004             return (const Header*)mBaseArray;
01005         }
01006 
01007         inline Header* GetHeader()
01008         {
01009             return (Header*)mBaseArray;
01010         }
01011 
01012         inline int GetHeaderOffset() const
01013         {
01014             return sizeof(Header);
01015         }
01016 
01017         inline int GetArrayCount() const
01018         {
01019             return GetHeader() ? GetHeader()->mArrayCount : 0;
01020         }
01021 
01022         inline void SetArrayCount(int pArrayCount)
01023         {
01024             if (GetHeader()) GetHeader()->mArrayCount = pArrayCount;
01025         }
01026 
01027         inline int GetBlockCount() const
01028         {
01029             return GetHeader() ? GetHeader()->mBlockCount : 0;
01030         }
01031 
01032         inline void SetBlockCount(int pArrayCount)
01033         {
01034             if (GetHeader()) GetHeader()->mBlockCount=pArrayCount;
01035         }
01036 
01037         char*       mBaseArray;
01038         TypeSize    mTypeSize;
01039     };
01040 
01041     // FbxArray<FbxArray<T> > is not supported.
01042     template <class Type> FBXSDK_INCOMPATIBLE_WITH_ARRAY_TEMPLATE(FbxArray<Type>);
01043 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
01044 
01045 #include <fbxsdk/fbxsdk_nsend.h>
01046 
01047 #endif /* _FBXSDK_CORE_BASE_ARRAY_H_ */