- Main Page
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# 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_ */