00001
00004 #ifndef _FBXSDK_KARRAYUL_H_
00005 #define _FBXSDK_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 <kbaselib_h.h>
00042
00043 #ifndef K_PLUGIN
00044 #include <klib/kdebug.h>
00045 #endif
00046
00047 #include <string.h>
00048 #include <stdlib.h>
00049
00050 #define KARRAYUL_BLOCKSIZE 4
00051
00052 #include <object/i/iobject.h>
00053
00054 #include <kbaselib_forward.h>
00055 #include <kbaselib_nsbegin.h>
00056
00057
00058
00059
00060 template< class Type > class KBaseStaticArray
00061 {
00062 protected:
00063 int mCount;
00064 Type *mArrayBuf;
00065
00066 public:
00067 inline int GetCount() { return mCount; }
00068
00070 inline Type &operator[](int pIndex)
00071 {
00072 #ifndef K_PLUGIN
00073 K_ASSERT_MSG( pIndex >= 0 , "Buffer underflow, appelle ton plombier.");
00074 K_ASSERT_MSG( pIndex < mCount,"Buffer overflow, appelle ton plombier.");
00075 #endif
00076 return mArrayBuf[pIndex];
00077 }
00078 };
00079
00080
00081 template< class Type, int Count > class KStaticArray : public KBaseStaticArray<Type>
00082 {
00083 public:
00084 Type mArray[Count];
00085 inline KStaticArray(){ this->mArrayBuf = mArray; this->mCount = Count;}
00086 };
00087
00088 template< class Type, int Count1, int Count2 > class KStaticArray2d
00089 {
00090 public:
00091 #if defined(KARCH_DEV_MSC) && (_MSC_VER <= 1200)// VC6
00092 KStaticArray<Type,Count2> *mArray;
00093
00094 KStaticArray2d() { mArray = new KStaticArray<Type,Count2>(Count1); }
00095 ~KStaticArray2d() { delete[] mArray; }
00096 #else
00097 KStaticArray<Type,Count2> mArray[Count1];
00098 #endif
00099
00100
00101 inline KStaticArray< Type, Count2 > &operator[](int pIndex)
00102 {
00103 #ifndef K_PLUGIN
00104 K_ASSERT_MSG( pIndex >= 0 , "Buffer underflow, appelle ton plombier.");
00105 K_ASSERT_MSG( pIndex < Count1,"Buffer overflow, appelle ton plombier.");
00106 #endif
00107 return mArray[pIndex];
00108 }
00109 };
00110
00111
00112
00113
00114 class KBaseArraySize {
00115 public:
00116 KBaseArraySize( int pItemSize)
00117 : mItemSize(pItemSize)
00118 {
00119 }
00120 inline int GetTypeSize() const { return mItemSize; }
00121 private:
00122 int mItemSize;
00123 };
00124
00125 template <class T> class KBaseArraySizeType
00126 {
00127 public:
00128 inline int GetTypeSize() const { return sizeof(T); }
00129 };
00130
00131
00132 KBASELIB_DLL void KBaseArrayFree(char*);
00133 KBASELIB_DLL char* KBaseArrayRealloc(char*, size_t);
00134
00136
00137
00138
00139
00140
00141
00143 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00144 KBASELIB_DLL void* KBaseArrayGetAlloc();
00145 #endif
00146
00147 template <class TypeSize> class KBaseArray
00148 {
00149 protected:
00150 struct KHeader {
00151 int mArrayCount;
00152 int mBlockCount;
00153 };
00154
00155
00156 protected:
00161 inline KBaseArray(TypeSize pTypeSize)
00162 : mTypeSize(pTypeSize)
00163 {
00164 mBaseArray = NULL;
00165 #ifndef K_PLUGIN
00166 K_ASSERT( pItemPerBlock > 0 );
00167 #endif
00168 }
00169
00170
00172 inline ~KBaseArray(){
00173 Clear ();
00174 }
00175
00183 inline int InsertAt(int pIndex, void *pItem)
00184 {
00185 int lArrayCount = GetArrayCount();
00186 int lBlockCount = GetBlockCount();
00187
00188 #ifndef K_PLUGIN
00189 K_ASSERT( pIndex >= 0 );
00190 #endif
00191
00192 if (pIndex>lArrayCount) {
00193 pIndex = GetArrayCount();
00194 }
00195
00196 if (lArrayCount>= lBlockCount*KARRAYUL_BLOCKSIZE)
00197 {
00198
00199
00200
00201 lBlockCount = ( 0 == lBlockCount ) ? 1 : lBlockCount * 2;
00202 mBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) (lBlockCount*KARRAYUL_BLOCKSIZE*GetTypeSize()) + GetHeaderOffset() );
00203 }
00204
00205 if (pIndex<lArrayCount)
00206 {
00207
00208 memmove (&(mBaseArray[(pIndex+1)*GetTypeSize()+ GetHeaderOffset() ]), &(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset()] ), GetTypeSize()*(lArrayCount-pIndex));
00209 }
00210
00211 memmove (&(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]), pItem, GetTypeSize());
00212
00213 SetArrayCount(lArrayCount+1);
00214 SetBlockCount(lBlockCount);
00215
00216 return pIndex;
00217 }
00218
00219
00226 inline void* GetAt(int pIndex) { return &(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]); }
00227
00234 inline void RemoveAt(int pIndex)
00235 {
00236
00237 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00238 if (!ValidateIndex( pIndex ))
00239 {
00240 return;
00241 }
00242 #endif
00243 int lArrayCount = GetArrayCount();
00244 if (pIndex+1<lArrayCount)
00245 {
00246 memmove (&(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]), &(mBaseArray[(pIndex+1)*GetTypeSize()+ GetHeaderOffset() ]), GetTypeSize()*(lArrayCount-pIndex-1));
00247 }
00248
00249 SetArrayCount( lArrayCount-1 );
00250
00251 #ifdef _DEBUG
00252 memset( &(mBaseArray[(GetArrayCount())*GetTypeSize()+ GetHeaderOffset() ]),0,GetTypeSize());
00253 #endif
00254 }
00255
00256
00262 inline bool ValidateIndex( int pIndex ) const
00263 {
00264 int lArrayCount = GetArrayCount();
00265 if (pIndex>=0 && pIndex<lArrayCount)
00266 {
00267 return true;
00268 } else
00269 {
00270 #ifndef K_PLUGIN
00271 K_ASSERT_MSG_NOW(_T("ArrayTemplate : Index out of range"));
00272 #endif
00273 return false;
00274 }
00275 }
00276
00277
00278 public:
00282 inline int GetCount() const { return GetArrayCount(); }
00283
00285 inline void Clear()
00286 {
00287 if (mBaseArray!=NULL)
00288 {
00289 KBaseArrayFree(mBaseArray);
00290 mBaseArray = NULL;
00291 }
00292 }
00293
00294
00296 inline void Empty()
00297 {
00298 #ifndef K_PLUGIN
00299 #ifdef _DEBUG
00300 memset( mBaseArray+ GetHeaderOffset() ,0,GetArrayCount()*GetTypeSize());
00301 #endif
00302 #endif
00303 SetArrayCount(0);
00304 }
00305
00306
00312 inline int Reserve(int pCapacity)
00313 {
00314
00315 #ifndef K_PLUGIN
00316 K_ASSERT( pCapacity > 0 );
00317 #endif
00318
00319 if( pCapacity )
00320 {
00321 const kUInt lTempNewBlockCount = ( (kUInt) (pCapacity + KARRAYUL_BLOCKSIZE - 1 ) / KARRAYUL_BLOCKSIZE );
00322 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00323
00324 int lArrayCount = GetArrayCount();
00325 int lBlockCount = GetBlockCount();
00326
00327 const kUInt lOldArraySize = lArrayCount*GetTypeSize();
00328 const kUInt lNewArraySize = lNewBlockCount*KARRAYUL_BLOCKSIZE*GetTypeSize();
00329
00330 if (lNewBlockCount != (kUInt) lBlockCount)
00331 mBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00332
00333 if( lNewBlockCount > (kUInt) lBlockCount ) {
00334 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00335 SetArrayCount(lArrayCount);
00336 } else if (pCapacity < lArrayCount)
00337 {
00338 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pCapacity*GetTypeSize(), 0, (size_t) (lNewArraySize-pCapacity*GetTypeSize()) );
00339 SetArrayCount(pCapacity);
00340 }
00341
00342 SetBlockCount(lNewBlockCount);
00343 }
00344
00345 return GetBlockCount()*KARRAYUL_BLOCKSIZE;
00346 }
00347
00348
00350
00351
00357 inline void SetCount (int pCount)
00358 {
00359 #ifndef K_PLUGIN
00360 #ifdef _DEBUG
00361 if (pCount<0)
00362 {
00363 K_ASSERT_MSG_NOW (_T("ArrayUL : Item count can't be negative"));
00364 return ;
00365 }
00366 #endif
00367 #endif
00368 int lArrayCount = GetArrayCount();
00369 if (pCount > lArrayCount)
00370 {
00371 AddMultiple( pCount-lArrayCount);
00372 } else
00373 {
00374 SetArrayCount(pCount);
00375 }
00376 }
00377
00378 inline void Resize(int pItemCount)
00379 {
00380 #ifndef K_PLUGIN
00381 K_ASSERT( pItemCount >= 0 );
00382 #endif
00383
00384 const kUInt lTempNewBlockCount = ( (kUInt) (pItemCount + KARRAYUL_BLOCKSIZE - 1 ) / KARRAYUL_BLOCKSIZE );
00385 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00386
00387 int lArrayCount = GetArrayCount();
00388 int lBlockCount = GetBlockCount();
00389
00390 const kUInt lOldArraySize = lArrayCount*GetTypeSize();
00391 const kUInt lNewArraySize = lNewBlockCount*KARRAYUL_BLOCKSIZE*GetTypeSize();
00392
00393 if (lNewBlockCount != (kUInt) lBlockCount)
00394 mBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00395
00396 if( lNewBlockCount > (kUInt) lBlockCount )
00397 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00398 else if (pItemCount < lArrayCount)
00399 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pItemCount*GetTypeSize(), 0, (size_t) (lNewArraySize-pItemCount*GetTypeSize()) );
00400
00401 SetBlockCount(lNewBlockCount);
00402 SetArrayCount(pItemCount);
00403 }
00404
00405 inline void AddMultiple(int pItemCount)
00406 {
00407 #ifndef K_PLUGIN
00408 K_ASSERT( pItemCount > 0 );
00409 #endif
00410
00411 if( pItemCount )
00412 {
00413 int lArrayCount = GetArrayCount();
00414 int lBlockCount = GetBlockCount();
00415 const kUInt lTempNewBlockCount = ( (kUInt) (lArrayCount+pItemCount + KARRAYUL_BLOCKSIZE - 1 ) / KARRAYUL_BLOCKSIZE );
00416 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00417
00418 const kUInt lOldArraySize = lArrayCount*GetTypeSize();
00419 const kUInt lNewArraySize = lNewBlockCount*KARRAYUL_BLOCKSIZE*GetTypeSize();
00420
00421 #ifndef K_PLUGIN
00422 K_ASSERT( lOldArraySize < lNewArraySize );
00423 #endif
00424
00425 if( lNewBlockCount > (kUInt) lBlockCount )
00426 {
00427 mBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset() );
00428 lBlockCount = lNewBlockCount;
00429 }
00430
00431 memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00432 SetArrayCount ( lArrayCount + pItemCount );
00433 SetBlockCount (lBlockCount);
00434 }
00435 }
00436
00437
00438 inline int GetTypeSize() const { return mTypeSize.GetTypeSize(); }
00439
00441
00442
00443
00444
00445
00446
00448 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00449
00450 protected:
00451 inline KHeader* const GetHeader() const
00452 {
00453 return (KHeader* const )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 protected:
00481 char* mBaseArray;
00482 TypeSize mTypeSize;
00483
00484 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00485
00486 };
00487
00488
00490 #define VC6
00491
00492 template < class Type > class KArrayTemplate : public KBaseArray< KBaseArraySizeType<Type> >
00493 {
00494 typedef KBaseArray< KBaseArraySizeType<Type> > ParentClass;
00495
00496
00497 public:
00501 inline KArrayTemplate()
00502 : ParentClass (KBaseArraySizeType<Type>())
00503 {
00504 }
00505
00507 inline KArrayTemplate(const KArrayTemplate& pArrayTemplate)
00508 : ParentClass (KBaseArraySizeType<Type>())
00509 {
00510 *this = pArrayTemplate;
00511 }
00512
00513 inline ~KArrayTemplate() {}
00514
00521 inline int InsertAt(int pIndex, Type pItem)
00522 {
00523 return ParentClass::InsertAt( pIndex,&pItem );
00524 }
00525
00530 inline Type RemoveAt(int pIndex)
00531 {
00532 Type tmpItem = GetAt(pIndex);
00533 ParentClass::RemoveAt( pIndex );
00534 return tmpItem;
00535 }
00536
00540 inline Type RemoveLast()
00541 {
00542 return RemoveAt(ParentClass::GetArrayCount()-1);
00543 }
00544
00549 inline bool RemoveIt(Type pItem)
00550 {
00551 int Index = Find (pItem);
00552 if (Index>=0)
00553 {
00554 RemoveAt (Index);
00555 return true;
00556 }
00557 return false;
00558 }
00559
00561 inline Type &operator[](int pIndex) const
00562 {
00563 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00564 if (!ParentClass::ValidateIndex( pIndex ))
00565 {
00566 return (Type &)(ParentClass::mBaseArray[(0)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00567 }
00568 #endif
00569 return (Type &)(ParentClass::mBaseArray[(pIndex)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00570 }
00571
00573 inline void SetAt(int pIndex, Type pItem)
00574 {
00575 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00576 if (!ParentClass::ValidateIndex( pIndex ))
00577 {
00578 return;
00579 }
00580 #endif
00581 GetArray()[pIndex] = pItem;
00582 }
00583
00585 inline void SetLast(Type pItem)
00586 {
00587 SetAt (ParentClass::GetArrayCount()-1, pItem);
00588 }
00589
00591 inline Type GetAt(int pIndex) const
00592 {
00593 #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00594 if (!ParentClass::ValidateIndex( pIndex ))
00595 {
00596 return (Type &)(ParentClass::mBaseArray[(0)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00597 }
00598 #endif
00599 return (Type &)(ParentClass::mBaseArray[(pIndex)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00600 }
00601
00605 inline Type GetFirst() const
00606 {
00607 #ifndef K_PLUGIN
00608 K_ASSERT( ParentClass::GetArrayCount() >= 1 );
00609 #endif
00610 return GetAt(0);
00611 }
00612
00616 inline Type GetLast() const
00617 {
00618 #ifndef K_PLUGIN
00619 K_ASSERT( ParentClass::GetArrayCount() >= 1 );
00620 #endif
00621 return GetAt(ParentClass::GetArrayCount()-1);
00622 }
00623
00628 inline int Find(Type pItem) const
00629 {
00630 return FindAfter( -1, pItem );
00631 }
00632
00638 inline int FindAfter(int pAfterIndex, Type pItem) const
00639 {
00640 #ifndef K_PLUGIN
00641 #ifdef _DEBUG
00642 if ( pAfterIndex > ParentClass::GetArrayCount() || pAfterIndex < -1 )
00643 {
00644 K_ASSERT_MSG_NOW (_T("ArrayUL : Search Begin Index out of range"));
00645 return -1;
00646 }
00647 #endif
00648 #endif
00649 int Count;
00650 for ( Count=pAfterIndex+1; Count<ParentClass::GetArrayCount(); Count++)
00651 {
00652 if (GetAt(Count)==pItem)
00653 {
00654 return Count;
00655 }
00656 }
00657 return -1;
00658 }
00659
00665 inline int FindBefore(int pBeforeIndex, Type pItem) const
00666 {
00667 #ifndef K_PLUGIN
00668 #ifdef _DEBUG
00669 if ( pBeforeIndex > ParentClass::GetArrayCount() || pBeforeIndex <= 0 )
00670 {
00671 K_ASSERT_MSG_NOW (_T("ArrayUL : Search Begin Index out of range"));
00672 return -1;
00673 }
00674 #endif
00675 #endif
00676 int Count;
00677 for ( Count=pBeforeIndex-1; Count>=0; Count--)
00678 {
00679 if (GetAt(Count)==pItem)
00680 {
00681 return Count;
00682 }
00683 }
00684 return -1;
00685 }
00686
00690 inline int Add(Type pItem)
00691 {
00692 return InsertAt(ParentClass::GetArrayCount(), pItem);
00693 }
00694
00698 inline int AddUnique(Type pItem)
00699 {
00700 int lReturnIndex = Find(pItem);
00701 if (lReturnIndex == -1)
00702 {
00703 lReturnIndex = Add(pItem);
00704 }
00705 return lReturnIndex;
00706 }
00707
00711 inline void AddMultiple( kUInt pItemCount )
00712 {
00713 ParentClass::AddMultiple( pItemCount );
00714 }
00715
00716 inline void AddArray(KArrayTemplate<Type> &pArray)
00717 {
00718 int lSourceIndex, lCount = pArray.GetCount();
00719 if( lCount == 0 ) return;
00720 int lDestinationIndex = ParentClass::GetCount();
00721 AddMultiple(lCount);
00722 for( lSourceIndex = 0; lSourceIndex < lCount; lSourceIndex++)
00723 {
00724 SetAt(lDestinationIndex++, pArray[lSourceIndex]);
00725 }
00726 }
00727
00728 inline void AddArrayNoDuplicate(KArrayTemplate<Type> &pArray)
00729 {
00730 int i, lCount = pArray.GetCount();
00731 for( i = 0; i < lCount; i++)
00732 {
00733 Type lItem = pArray[i];
00734 if (Find(lItem) == -1)
00735 {
00736 Add(lItem);
00737 }
00738 }
00739 }
00740 inline void RemoveArray(KArrayTemplate<Type> &pArray)
00741 {
00742 int lRemoveIndex, lRemoveCount = pArray.GetCount();
00743 for( lRemoveIndex = 0; lRemoveIndex < lRemoveCount; lRemoveIndex++)
00744 {
00745 RemoveIt(pArray[lRemoveIndex]);
00746 }
00747 }
00748
00750 inline Type* GetArray() const
00751 {
00752 if (ParentClass::mBaseArray == NULL)
00753 return NULL;
00754
00755 return (Type*)(ParentClass::mBaseArray+ ParentClass::GetHeaderOffset()) ;
00756 }
00757
00759 inline KArrayTemplate<Type>& operator=(const KArrayTemplate<Type>& pArrayTemplate)
00760 {
00761 ParentClass::Clear();
00762
00763 int i, lCount = pArrayTemplate.GetCount();
00764
00765 for (i = 0; i < lCount; i++)
00766 {
00767 Add(pArrayTemplate[i]);
00768 }
00769
00770 return (*this);
00771 }
00772
00773 #ifdef K_PLUGIN
00775 inline operator Type* ()
00776 {
00777 return GetArray();
00778 }
00779 #endif
00780 };
00781
00783
00784
00785
00786
00787
00788
00790
00791 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00792
00793 template <class Type> inline void DeleteAndClear(KArrayTemplate<Type>& Array)
00794 {
00795 kUInt lItemCount = Array.GetCount();
00796 while( lItemCount )
00797 {
00798 lItemCount--;
00799 Type& Item = (Array.operator[](lItemCount));
00800 delete Item;
00801 Item = NULL;
00802 }
00803 Array.Clear();
00804 }
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 typedef class KBASELIB_DLL KArrayTemplate<int *> KArrayHkInt;
00819 typedef class KBASELIB_DLL KArrayTemplate<kUInt *> KArrayHkUInt;
00820 typedef class KBASELIB_DLL KArrayTemplate<double *> KArrayHkDouble;
00821 typedef class KBASELIB_DLL KArrayTemplate<float *> KArrayHkFloat;
00822 typedef class KBASELIB_DLL KArrayTemplate<void *> KArrayVoid;
00823 typedef class KBASELIB_DLL KArrayTemplate<char *> KArrayChar;
00824 typedef class KBASELIB_DLL KArrayTemplate<int> KArraykInt;
00825 typedef class KBASELIB_DLL KArrayTemplate<kUInt> KArraykUInt;
00826 typedef class KBASELIB_DLL KArrayTemplate<float> KArraykFloat;
00827 typedef class KBASELIB_DLL KArrayTemplate<double> KArraykDouble;
00828
00829 typedef class KBASELIB_DLL KArrayTemplate<kReference> KArrayUL;
00830
00831 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00832
00833 #include <kbaselib_nsend.h>
00834
00835 #endif // #define _FBXSDK_KARRAYUL_H_
00836
00837