00001
00004 #ifndef FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KARRAYUL_H
00005 #define FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KARRAYUL_H
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <fbxfilesdk/fbxfilesdk_def.h>
00042
00043 #include <fbxfilesdk/components/kbaselib/klib/kdebug.h>
00044
00045 #define KFBX_ARRAYUL_BLOCKSIZE 4
00046
00047 #include <fbxfilesdk/fbxfilesdk_nsbegin.h>
00048
00049
00050
00051
00052 template< class Type > class KBaseStaticArray
00053 {
00054 protected:
00055 int mCount;
00056 Type *mArrayBuf;
00057
00058 public:
00059 inline int GetCount() { return mCount; }
00060
00062 inline Type &operator[](int pIndex)
00063 {
00064 #ifdef KFBX_PRIVATE
00065 K_ASSERT_MSG( pIndex >= 0 , "Buffer underflow");
00066 K_ASSERT_MSG( pIndex < mCount,"Buffer overflow.");
00067 #endif
00068 return mArrayBuf[pIndex];
00069 }
00070 };
00071
00072
00073 template< class Type, int Count > class KStaticArray : public KBaseStaticArray<Type>
00074 {
00075 public:
00076 Type mArray[Count];
00077 inline KStaticArray(){ this->mArrayBuf = mArray; this->mCount = Count;}
00078 };
00079
00080 template< class Type, int Count1, int Count2 > class KStaticArray2d
00081 {
00082 public:
00083 KStaticArray<Type,Count2> mArray[Count1];
00084
00085
00086 inline KStaticArray< Type, Count2 > &operator[](int pIndex)
00087 {
00088 #ifdef KFBX_PRIVATE
00089 K_ASSERT_MSG( pIndex >= 0 , "Buffer underflow.");
00090 K_ASSERT_MSG( pIndex < Count1,"Buffer overflow.");
00091 #endif
00092 return mArray[pIndex];
00093 }
00094 };
00095
00096
00097
00098
00099 class KBaseArraySize {
00100 public:
00101 KBaseArraySize( int pItemSize)
00102 : mItemSize(pItemSize)
00103 {
00104 }
00105 inline int GetTypeSize() const { return mItemSize; }
00106 private:
00107 int mItemSize;
00108 };
00109
00110
00111 KFBX_DLL void KBaseArrayFree(char*);
00112 KFBX_DLL char* KBaseArrayRealloc(char*, size_t);
00113
00115
00116
00117
00118
00119
00120
00122 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00123 KFBX_DLL void* KBaseArrayGetAlloc();
00124 #endif
00125
00129 template <class TypeSize>
00130 class KBaseArray
00131 {
00133
00134
00135
00136
00137
00138
00140 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00141
00142 protected:
00143 struct KHeader
00144 {
00145 int mArrayCount;
00146 int mBlockCount;
00147 };
00148
00152 inline KBaseArray(TypeSize pTypeSize)
00153 : mTypeSize(pTypeSize)
00154 {
00155 mBaseArray = NULL;
00156 }
00157
00159 inline ~KBaseArray()
00160 {
00161 Clear();
00162 }
00163
00164 inline int GetTypeSize() const { return mTypeSize.GetTypeSize(); }
00165
00169 inline int GetCount() const { return GetArrayCount(); }
00170
00174 inline void Clear()
00175 {
00176 if (mBaseArray!=NULL)
00177 {
00178 KBaseArrayFree(mBaseArray);
00179 mBaseArray = NULL;
00180 }
00181 }
00182
00186 inline void Empty()
00187 {
00188 #ifdef KFBX_PRIVATE
00189 #ifdef _DEBUG
00190 memset(mBaseArray+ GetHeaderOffset(), 0, GetArrayCount()*GetTypeSize());
00191 #endif
00192 #endif
00193
00194 SetArrayCount(0);
00195 }
00196
00202 inline int Reserve(int pCapacity)
00203 {
00204 #ifdef KFBX_PRIVATE
00205 K_ASSERT( pCapacity > 0 );
00206 #endif
00207
00208 if( pCapacity )
00209 {
00210 const kUInt lTempNewBlockCount = ( (kUInt) (pCapacity + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00211 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00212
00213 int lArrayCount = GetArrayCount();
00214 int lBlockCount = GetBlockCount();
00215
00216 const kUInt lOldArraySize = lArrayCount*GetTypeSize();
00217 const kUInt lNewArraySize = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*GetTypeSize();
00218
00219 if (lNewBlockCount != (kUInt) lBlockCount)
00220 {
00221 char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00222 if (!lBaseArray)
00223 return GetBlockCount()*KFBX_ARRAYUL_BLOCKSIZE;
00224 mBaseArray = lBaseArray;
00225 }
00226
00227 if( lNewBlockCount > (kUInt) lBlockCount ) {
00228 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00229 SetArrayCount(lArrayCount);
00230 } else if (pCapacity < lArrayCount)
00231 {
00232 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pCapacity*GetTypeSize(), 0, (size_t) (lNewArraySize-pCapacity*GetTypeSize()) );
00233 SetArrayCount(pCapacity);
00234 }
00235
00236 SetBlockCount(lNewBlockCount);
00237 }
00238
00239 return GetBlockCount()*KFBX_ARRAYUL_BLOCKSIZE;
00240 }
00241
00248 inline void SetCount(int pCount)
00249 {
00250 #ifdef KFBX_PRIVATE
00251 #ifdef _DEBUG
00252 if (pCount<0)
00253 {
00254 K_ASSERT_MSG_NOW (_T("ArrayUL : Item count can't be negative"));
00255 return ;
00256 }
00257 #endif
00258 #endif
00259 int lArrayCount = GetArrayCount();
00260 if (pCount > lArrayCount)
00261 {
00262 AddMultiple( pCount-lArrayCount);
00263 } else
00264 {
00265 SetArrayCount(pCount);
00266 }
00267 }
00268
00275 inline void Resize(int pItemCount)
00276 {
00277 #ifdef KFBX_PRIVATE
00278 K_ASSERT( pItemCount >= 0 );
00279 #endif
00280
00281 const kUInt lTempNewBlockCount = ( (kUInt) (pItemCount + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00282 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00283
00284 int lArrayCount = GetArrayCount();
00285 int lBlockCount = GetBlockCount();
00286
00287 const kUInt lOldArraySize = lArrayCount*GetTypeSize();
00288 const kUInt lNewArraySize = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*GetTypeSize();
00289
00290 if (lNewBlockCount != (kUInt) lBlockCount)
00291 {
00292 char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00293 if (!lBaseArray)
00294 return;
00295 mBaseArray = lBaseArray;
00296 }
00297
00298 if( lNewBlockCount > (kUInt) lBlockCount )
00299 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00300 else if (pItemCount < lArrayCount)
00301 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pItemCount*GetTypeSize(), 0, (size_t) (lNewArraySize-pItemCount*GetTypeSize()) );
00302
00303 SetBlockCount(lNewBlockCount);
00304 SetArrayCount(pItemCount);
00305 }
00306
00313 inline void AddMultiple(int pItemCount)
00314 {
00315 #ifdef KFBX_PRIVATE
00316 K_ASSERT( pItemCount > 0 );
00317 #endif
00318
00319 if( pItemCount )
00320 {
00321 int lArrayCount = GetArrayCount();
00322 int lBlockCount = GetBlockCount();
00323 const kUInt lTempNewBlockCount = ( (kUInt) (lArrayCount+pItemCount + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00324 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00325
00326 const kUInt lOldArraySize = lArrayCount*GetTypeSize();
00327 const kUInt lNewArraySize = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*GetTypeSize();
00328
00329 #ifdef KFBX_PRIVATE
00330 K_ASSERT( lOldArraySize < lNewArraySize );
00331 #endif
00332
00333 if( lNewBlockCount > (kUInt) lBlockCount )
00334 {
00335 char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00336 if (!lBaseArray)
00337 return;
00338 mBaseArray = lBaseArray;
00339 lBlockCount = lNewBlockCount;
00340 }
00341
00342 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00343 SetArrayCount ( lArrayCount + pItemCount );
00344 SetBlockCount (lBlockCount);
00345 }
00346 }
00347
00355 inline int InsertAt(int pIndex, void *pItem)
00356 {
00357 int lArrayCount = GetArrayCount();
00358 int lBlockCount = GetBlockCount();
00359
00360 #ifdef KFBX_PRIVATE
00361 K_ASSERT( pIndex >= 0 );
00362 #endif
00363
00364 if (pIndex>lArrayCount) {
00365 pIndex = GetArrayCount();
00366 }
00367
00368 if (lArrayCount>= lBlockCount*KFBX_ARRAYUL_BLOCKSIZE)
00369 {
00370
00371
00372
00373 lBlockCount = ( 0 == lBlockCount ) ? 1 : lBlockCount * 2;
00374 char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) (lBlockCount*KFBX_ARRAYUL_BLOCKSIZE*GetTypeSize()) + GetHeaderOffset() );
00375 if(!lBaseArray)
00376 return -1;
00377 mBaseArray = lBaseArray;
00378 }
00379
00380 if (pIndex<lArrayCount)
00381 {
00382
00383 memmove (&(mBaseArray[(pIndex+1)*GetTypeSize()+ GetHeaderOffset() ]), &(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset()] ), GetTypeSize()*(lArrayCount-pIndex));
00384 }
00385
00386 memmove (&(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]), pItem, GetTypeSize());
00387
00388 SetArrayCount(lArrayCount+1);
00389 SetBlockCount(lBlockCount);
00390
00391 return pIndex;
00392 }
00393
00394
00401 inline void* GetAt(int pIndex) { return &(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]); }
00402
00409 inline void RemoveAt(int pIndex)
00410 {
00411 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00412 if (!ValidateIndex( pIndex ))
00413 {
00414 return;
00415 }
00416 #endif
00417 int lArrayCount = GetArrayCount();
00418 if (pIndex+1<lArrayCount)
00419 {
00420 memmove (&(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]), &(mBaseArray[(pIndex+1)*GetTypeSize()+ GetHeaderOffset() ]), GetTypeSize()*(lArrayCount-pIndex-1));
00421 }
00422
00423 SetArrayCount( lArrayCount-1 );
00424
00425 #ifdef _DEBUG
00426 memset( &(mBaseArray[(GetArrayCount())*GetTypeSize()+ GetHeaderOffset() ]),0,GetTypeSize());
00427 #endif
00428 }
00429
00435 inline bool ValidateIndex( int pIndex ) const
00436 {
00437 int lArrayCount = GetArrayCount();
00438 if (pIndex>=0 && pIndex<lArrayCount)
00439 {
00440 return true;
00441 }
00442 else
00443 {
00444 #ifdef KFBX_PRIVATE
00445 K_ASSERT_MSG_NOW(_T("ArrayTemplate : Index out of range"));
00446 #endif
00447 return false;
00448 }
00449 }
00450
00451 inline const KHeader* GetHeader() const
00452 {
00453 return (const KHeader *)mBaseArray;
00454 }
00455 inline KHeader* GetHeader()
00456 {
00457 return (KHeader*)mBaseArray;
00458 }
00459 inline int GetHeaderOffset() const
00460 {
00461 return sizeof(KHeader);
00462 }
00463 inline int GetArrayCount() const
00464 {
00465 return GetHeader() ? GetHeader()->mArrayCount : 0;
00466 }
00467 inline void SetArrayCount(int pArrayCount)
00468 {
00469 if (GetHeader()) GetHeader()->mArrayCount = pArrayCount;
00470 }
00471 inline int GetBlockCount() const
00472 {
00473 return GetHeader() ? GetHeader()->mBlockCount : 0;
00474 }
00475 inline void SetBlockCount(int pArrayCount)
00476 {
00477 if (GetHeader()) GetHeader()->mBlockCount=pArrayCount;
00478 }
00479
00480 char* mBaseArray;
00481 TypeSize mTypeSize;
00482
00483 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00484 };
00485
00490 template <size_t TypeSize> class KBaseArrayFast
00491 {
00492 public:
00496 inline int GetCount() const { return GetArrayCount(); }
00497
00499 inline void Clear()
00500 {
00501 if (mBaseArray!=NULL)
00502 {
00503 KBaseArrayFree(mBaseArray);
00504 mArrayCount = 0;
00505 mBaseArray = NULL;
00506 }
00507 }
00508
00509
00511 inline void Empty()
00512 {
00513 #ifdef KFBX_PRIVATE
00514 #ifdef _DEBUG
00515 memset( mBaseArray+ GetHeaderOffset() ,0,GetArrayCount()*TypeSize);
00516 #endif
00517 #endif
00518 SetArrayCount(0);
00519 }
00520
00521
00527 inline int Reserve(int pCapacity)
00528 {
00529 #ifdef KFBX_PRIVATE
00530 K_ASSERT( pCapacity > 0 );
00531 #endif
00532
00533 if( pCapacity )
00534 {
00535 const kUInt lTempNewBlockCount = ( (kUInt) (pCapacity + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00536 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00537
00538 int lArrayCount = GetArrayCount();
00539 int lBlockCount = GetBlockCount();
00540
00541 const kUInt lOldArraySize = lArrayCount*TypeSize;
00542 const kUInt lNewArraySize = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*TypeSize;
00543
00544 if (lNewBlockCount != (kUInt) lBlockCount)
00545 {
00546 char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00547 if (!lBaseArray)
00548 return GetBlockCount()*KFBX_ARRAYUL_BLOCKSIZE;
00549 mBaseArray = lBaseArray;
00550 }
00551
00552 if( lNewBlockCount > (kUInt) lBlockCount ) {
00553 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00554 SetArrayCount(lArrayCount);
00555 } else if (pCapacity < lArrayCount)
00556 {
00557 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pCapacity*TypeSize, 0, (size_t) (lNewArraySize-pCapacity*TypeSize) );
00558 SetArrayCount(pCapacity);
00559 }
00560
00561 SetBlockCount(lNewBlockCount);
00562 }
00563
00564 return GetBlockCount()*KFBX_ARRAYUL_BLOCKSIZE;
00565 }
00566
00567
00569
00570
00576 inline void SetCount (int pCount)
00577 {
00578 #ifdef KFBX_PRIVATE
00579 #ifdef _DEBUG
00580 if (pCount<0)
00581 {
00582 K_ASSERT_MSG_NOW (_T("ArrayUL : Item count can't be negative"));
00583 return ;
00584 }
00585 #endif
00586 #endif
00587 int lArrayCount = GetArrayCount();
00588 if (pCount > lArrayCount)
00589 {
00590 AddMultiple( pCount-lArrayCount);
00591 } else
00592 {
00593 SetArrayCount(pCount);
00594 }
00595 }
00596
00597 inline void Resize(int pItemCount)
00598 {
00599 #ifdef KFBX_PRIVATE
00600 K_ASSERT( pItemCount >= 0 );
00601 #endif
00602
00603 const kUInt lTempNewBlockCount = ( (kUInt) (pItemCount + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00604 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00605
00606 int lArrayCount = GetArrayCount();
00607 int lBlockCount = GetBlockCount();
00608
00609 const kUInt lOldArraySize = lArrayCount*TypeSize;
00610 const kUInt lNewArraySize = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*TypeSize;
00611
00612 if (lNewBlockCount != (kUInt) lBlockCount)
00613 {
00614 char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00615 if (!lBaseArray)
00616 return;
00617 mBaseArray = lBaseArray;
00618 }
00619
00620 if( lNewBlockCount > (kUInt) lBlockCount )
00621 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00622 else if (pItemCount < lArrayCount)
00623 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pItemCount*TypeSize, 0, (size_t) (lNewArraySize-pItemCount*TypeSize) );
00624
00625 SetBlockCount(lNewBlockCount);
00626 SetArrayCount(pItemCount);
00627 }
00628
00629 inline void AddMultiple(int pItemCount)
00630 {
00631 #ifdef KFBX_PRIVATE
00632 K_ASSERT( pItemCount > 0 );
00633 #endif
00634
00635 if( pItemCount )
00636 {
00637 int lArrayCount = GetArrayCount();
00638 int lBlockCount = GetBlockCount();
00639 const kUInt lTempNewBlockCount = ( (kUInt) (lArrayCount+pItemCount + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00640 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00641
00642 const kUInt lOldArraySize = lArrayCount*TypeSize;
00643 const kUInt lNewArraySize = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*TypeSize;
00644
00645 #ifdef KFBX_PRIVATE
00646 K_ASSERT( lOldArraySize < lNewArraySize );
00647 #endif
00648
00649 if( lNewBlockCount > (kUInt) lBlockCount )
00650 {
00651 char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00652 if (!lBaseArray)
00653 return;
00654 mBaseArray = lBaseArray;
00655 lBlockCount = lNewBlockCount;
00656 }
00657
00658 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00659 SetArrayCount ( lArrayCount + pItemCount );
00660 SetBlockCount (lBlockCount);
00661 }
00662 }
00663
00665
00666
00667
00668
00669
00670
00672 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00673
00674
00675 protected:
00676 struct KHeader {
00677 int mBlockCount;
00678 };
00679
00680
00681 protected:
00683 inline KBaseArrayFast()
00684 :mArrayCount(0), mBaseArray(NULL)
00685 {
00686 }
00687
00688
00690 inline ~KBaseArrayFast(){
00691 Clear ();
00692 }
00693
00701 inline int InsertAt(int pIndex, void *pItem)
00702 {
00703 int lArrayCount = GetArrayCount();
00704 int lBlockCount = GetBlockCount();
00705
00706 #ifdef KFBX_PRIVATE
00707 K_ASSERT( pIndex >= 0 );
00708 #endif
00709
00710 if (pIndex>lArrayCount) {
00711 pIndex = GetArrayCount();
00712 }
00713
00714 if (lArrayCount>= lBlockCount*KFBX_ARRAYUL_BLOCKSIZE)
00715 {
00716
00717
00718
00719 lBlockCount = ( 0 == lBlockCount ) ? 1 : lBlockCount * 2;
00720 char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) (lBlockCount*KFBX_ARRAYUL_BLOCKSIZE*TypeSize) + GetHeaderOffset() );
00721 if(!lBaseArray)
00722 return -1;
00723 mBaseArray = lBaseArray;
00724 }
00725
00726 if (pIndex<lArrayCount)
00727 {
00728
00729 memmove (&(mBaseArray[(pIndex+1)*TypeSize+ GetHeaderOffset() ]), &(mBaseArray[(pIndex)*TypeSize+ GetHeaderOffset()] ), TypeSize*(lArrayCount-pIndex));
00730 }
00731
00732 memmove (&(mBaseArray[(pIndex)*TypeSize+ GetHeaderOffset() ]), pItem, TypeSize);
00733
00734 SetArrayCount(lArrayCount+1);
00735 SetBlockCount(lBlockCount);
00736
00737 return pIndex;
00738 }
00739
00740
00747 inline void* GetAt(int pIndex) { return &(mBaseArray[(pIndex)*TypeSize+ GetHeaderOffset() ]); }
00748
00755 inline void RemoveAt(int pIndex)
00756 {
00757
00758 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00759 if (!ValidateIndex( pIndex ))
00760 {
00761 return;
00762 }
00763 #endif
00764 int lArrayCount = GetArrayCount();
00765 if (pIndex+1<lArrayCount)
00766 {
00767 memmove (&(mBaseArray[(pIndex)*TypeSize+ GetHeaderOffset() ]), &(mBaseArray[(pIndex+1)*TypeSize+ GetHeaderOffset() ]), TypeSize*(lArrayCount-pIndex-1));
00768 }
00769
00770 SetArrayCount( lArrayCount-1 );
00771
00772 #ifdef _DEBUG
00773 memset( &(mBaseArray[(GetArrayCount())*TypeSize+ GetHeaderOffset() ]),0,TypeSize);
00774 #endif
00775 }
00776
00777
00783 inline bool ValidateIndex( int pIndex ) const
00784 {
00785 int lArrayCount = GetArrayCount();
00786 if (pIndex>=0 && pIndex<lArrayCount)
00787 {
00788 return true;
00789 } else
00790 {
00791 #ifdef KFBX_PRIVATE
00792 K_ASSERT_MSG_NOW(_T("ArrayTemplate : Index out of range"));
00793 #endif
00794 return false;
00795 }
00796 }
00797
00798 protected:
00799 inline KHeader* const GetHeader() const
00800 {
00801 return (KHeader* const)mBaseArray;
00802 }
00803 inline KHeader* GetHeader()
00804 {
00805 return (KHeader*)mBaseArray;
00806 }
00807 inline int GetHeaderOffset() const
00808 {
00809 return sizeof(KHeader);
00810 }
00811 inline int GetArrayCount() const
00812 {
00813 return mArrayCount;
00814 }
00815 inline void SetArrayCount(int pArrayCount)
00816 {
00817 mArrayCount = pArrayCount;
00818 }
00819 inline int GetBlockCount() const
00820 {
00821 return GetHeader() ? GetHeader()->mBlockCount : 0;
00822 }
00823 inline void SetBlockCount(int pArrayCount)
00824 {
00825 if (GetHeader()) GetHeader()->mBlockCount = pArrayCount;
00826 }
00827
00828 protected:
00829 int mArrayCount;
00830 char* mBaseArray;
00831
00832 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00833 };
00834
00838 template < class Type >
00839 class KArrayTemplate : public KBaseArrayFast< sizeof(Type) >
00840 {
00841 typedef KBaseArrayFast< sizeof(Type) > ParentClass;
00842
00843 #ifdef _MSC_VER
00844
00845
00846
00847
00848 K_STATIC_ASSERT(
00849 KFBX_IS_SIMPLE_TYPE(Type)
00850 || __is_enum(Type)
00851 || (__has_trivial_constructor(Type)&&__has_trivial_destructor(Type))
00852 || !KFBX_IS_INCOMPATIBLE_WITH_KARRAYTEMPLATE(Type)
00853 );
00854 #endif
00855
00856 public:
00858 inline KArrayTemplate()
00859 : ParentClass ()
00860 {
00861 }
00862
00864 inline KArrayTemplate(const KArrayTemplate& pArrayTemplate)
00865 : ParentClass ()
00866 {
00867 *this = pArrayTemplate;
00868 }
00869
00871 inline ~KArrayTemplate() {}
00872
00879 inline int InsertAt(int pIndex, Type pItem)
00880 {
00881 return ParentClass::InsertAt( pIndex,&pItem );
00882 }
00883
00889 inline Type RemoveAt(int pIndex)
00890 {
00891 Type tmpItem = GetAt(pIndex);
00892 ParentClass::RemoveAt( pIndex );
00893 return tmpItem;
00894 }
00895
00900 inline Type RemoveLast()
00901 {
00902 return RemoveAt(ParentClass::GetArrayCount()-1);
00903 }
00904
00909 inline bool RemoveIt(Type pItem)
00910 {
00911 int Index = Find (pItem);
00912 if (Index>=0)
00913 {
00914 RemoveAt (Index);
00915 return true;
00916 }
00917 return false;
00918 }
00919
00925 inline Type &operator[](int pIndex) const
00926 {
00927 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00928 if (!ParentClass::ValidateIndex( pIndex ))
00929 {
00930 return (Type &)(ParentClass::mBaseArray[(0)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00931 }
00932 #endif
00933 return (Type &)(ParentClass::mBaseArray[(pIndex)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00934 }
00935
00941 inline void SetAt(int pIndex, Type pItem)
00942 {
00943 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00944 if (!ParentClass::ValidateIndex( pIndex ))
00945 {
00946 return;
00947 }
00948 #endif
00949 GetArray()[pIndex] = pItem;
00950 }
00951
00956 inline void SetLast(Type pItem)
00957 {
00958 SetAt (ParentClass::GetArrayCount()-1, pItem);
00959 }
00960
00966 inline Type GetAt(int pIndex) const
00967 {
00968 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00969 if (!ParentClass::ValidateIndex( pIndex ))
00970 {
00971 return (Type &)(ParentClass::mBaseArray[(0)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00972 }
00973 #endif
00974 return (Type &)(ParentClass::mBaseArray[(pIndex)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00975 }
00976
00981 inline Type GetFirst() const
00982 {
00983 #ifdef KFBX_PRIVATE
00984 K_ASSERT( ParentClass::GetArrayCount() >= 1 );
00985 #endif
00986 return GetAt(0);
00987 }
00988
00993 inline Type GetLast() const
00994 {
00995 #ifdef KFBX_PRIVATE
00996 K_ASSERT( ParentClass::GetArrayCount() >= 1 );
00997 #endif
00998 return GetAt(ParentClass::GetArrayCount()-1);
00999 }
01000
01005 inline int Find(Type pItem) const
01006 {
01007 return FindAfter( -1, pItem );
01008 }
01009
01016 inline int FindAfter(int pAfterIndex, Type pItem) const
01017 {
01018 #ifdef KFBX_PRIVATE
01019 #ifdef _DEBUG
01020 if ( pAfterIndex > ParentClass::GetArrayCount() || pAfterIndex < -1 )
01021 {
01022 K_ASSERT_MSG_NOW (_T("ArrayUL : Search Begin Index out of range"));
01023 return -1;
01024 }
01025 #endif
01026 #endif
01027 int Count;
01028 for ( Count=pAfterIndex+1; Count<ParentClass::GetArrayCount(); Count++)
01029 {
01030 if (GetAt(Count)==pItem)
01031 {
01032 return Count;
01033 }
01034 }
01035 return -1;
01036 }
01037
01044 inline int FindBefore(int pBeforeIndex, Type pItem) const
01045 {
01046 #ifdef KFBX_PRIVATE
01047 #ifdef _DEBUG
01048 if ( pBeforeIndex > ParentClass::GetArrayCount() || pBeforeIndex <= 0 )
01049 {
01050 K_ASSERT_MSG_NOW (_T("ArrayUL : Search Begin Index out of range"));
01051 return -1;
01052 }
01053 #endif
01054 #endif
01055 int Count;
01056 for ( Count=pBeforeIndex-1; Count>=0; Count--)
01057 {
01058 if (GetAt(Count)==pItem)
01059 {
01060 return Count;
01061 }
01062 }
01063 return -1;
01064 }
01065
01070 inline int Add(Type pItem)
01071 {
01072 return InsertAt(ParentClass::GetArrayCount(), pItem);
01073 }
01074
01079 inline int AddUnique(Type pItem)
01080 {
01081 int lReturnIndex = Find(pItem);
01082 if (lReturnIndex == -1)
01083 {
01084 lReturnIndex = Add(pItem);
01085 }
01086 return lReturnIndex;
01087 }
01088
01092 inline void AddMultiple(kUInt pItemCount)
01093 {
01094 ParentClass::AddMultiple(pItemCount);
01095 }
01096
01100 inline void AddArray(const KArrayTemplate<Type> &pArray)
01101 {
01102 int lSourceIndex, lCount = pArray.GetCount();
01103 if( lCount == 0 ) return;
01104 int lDestinationIndex = ParentClass::GetCount();
01105 AddMultiple(lCount);
01106 for( lSourceIndex = 0; lSourceIndex < lCount; lSourceIndex++)
01107 {
01108 SetAt(lDestinationIndex++, pArray[lSourceIndex]);
01109 }
01110 }
01111
01115 inline void AddArrayNoDuplicate(const KArrayTemplate<Type> &pArray)
01116 {
01117 int i, lCount = pArray.GetCount();
01118 for( i = 0; i < lCount; i++)
01119 {
01120 Type lItem = pArray[i];
01121 if (Find(lItem) == -1)
01122 {
01123 Add(lItem);
01124 }
01125 }
01126 }
01127
01131 inline void RemoveArray(const KArrayTemplate<Type> &pArray)
01132 {
01133 int lRemoveIndex, lRemoveCount = pArray.GetCount();
01134 for( lRemoveIndex = 0; lRemoveIndex < lRemoveCount; lRemoveIndex++)
01135 {
01136 RemoveIt(pArray[lRemoveIndex]);
01137 }
01138 }
01139
01141 inline Type* GetArray() const
01142 {
01143 if (ParentClass::mBaseArray == NULL)
01144 return NULL;
01145
01146 return (Type*)(ParentClass::mBaseArray+ ParentClass::GetHeaderOffset()) ;
01147 }
01148
01150 inline KArrayTemplate<Type>& operator=(const KArrayTemplate<Type>& pArrayTemplate)
01151 {
01152 if ( this != &pArrayTemplate )
01153 {
01154 ParentClass::Clear();
01155
01156 int i, lCount = pArrayTemplate.GetCount();
01157
01158 for (i = 0; i < lCount; i++)
01159 {
01160 Add(pArrayTemplate[i]);
01161 }
01162 }
01163
01164 return (*this);
01165 }
01166
01168 inline operator Type* ()
01169 {
01170 return GetArray();
01171 }
01172 };
01173
01175
01176
01177
01178
01179
01180
01182
01183
01184 template < class Type > KFBX_INCOMPATIBLE_WITH_KARRAYTEMPLATE_TEMPLATE(KArrayTemplate<Type>);
01185
01186 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01187 template <class Type> inline void FbxSdkDeleteAndClear(KArrayTemplate<Type>& Array)
01188 {
01189 kUInt lItemCount = Array.GetCount();
01190 while( lItemCount )
01191 {
01192 lItemCount--;
01193 Type& Item = (Array.operator[](lItemCount));
01194 FbxSdkDelete(Item);
01195 Item = NULL;
01196 }
01197 Array.Clear();
01198 }
01199
01200 template <class Type> inline void DeleteAndClear(KArrayTemplate<Type>& Array)
01201 {
01202 kUInt lItemCount = Array.GetCount();
01203 while( lItemCount )
01204 {
01205 lItemCount--;
01206 Type& Item = (Array.operator[](lItemCount));
01207 delete Item;
01208 Item = NULL;
01209 }
01210 Array.Clear();
01211 }
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225 typedef class KFBX_DLL KArrayTemplate<int *> KArrayHkInt;
01226 typedef class KFBX_DLL KArrayTemplate<kUInt *> KArrayHkUInt;
01227 typedef class KFBX_DLL KArrayTemplate<double *> KArrayHkDouble;
01228 typedef class KFBX_DLL KArrayTemplate<float *> KArrayHkFloat;
01229 typedef class KFBX_DLL KArrayTemplate<void *> KArrayVoid;
01230 typedef class KFBX_DLL KArrayTemplate<char *> KArrayChar;
01231 typedef class KFBX_DLL KArrayTemplate<int> KIntArray;
01232 typedef class KFBX_DLL KArrayTemplate<kUInt> KUIntArray;
01233 typedef class KFBX_DLL KArrayTemplate<float> KFloatArray;
01234 typedef class KFBX_DLL KArrayTemplate<double> KDoubleArray;
01235
01236 typedef class KFBX_DLL KArrayTemplate<kReference> KArrayUL;
01237
01238 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
01239
01240 #include <fbxfilesdk/fbxfilesdk_nsend.h>
01241
01242 #endif // FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KARRAYUL_H
01243