00001
00002
00003
00004
00005
00006
00007
00008
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
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
00192
00193
00194
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
00234
00235
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
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
00357
00358
00359
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
00685
00686
00687
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
00924
00925
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
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
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