00001
00002
00012
00013
00014 #ifndef __SL_ARRAY_H__
00015 #define __SL_ARRAY_H__
00016
00017 #if defined(_WIN32) || defined(_WIN32_WCE) || defined(_XBOX)
00018
00019 #pragma warning( disable : 4786 )
00020 #endif // defined(_WIN32) || defined(_WIN32_WCE)
00021
00022 #include <SIBCArray.h>
00023 #include "SL_Int.h"
00024 #include <new.h>
00025
00026
00027 #if defined(_WIN32) || defined(_WIN32_WCE) || defined(_XBOX)
00028 #pragma pack(push,4)
00029 #elif defined(CODEWARRIOR)
00030 #pragma options align= mac86k4byte
00031 #endif
00032
00065 template <class CElemType, class CSubElemType, SI_Int StructSize>
00066 class XSIEXPORT CSLArrayProxy
00067 {
00068 public:
00073 CSLArrayProxy( CdotXSITemplate *in_pTemplate, SI_Long in_Index);
00074
00077 CSLArrayProxy();
00078
00082 ~CSLArrayProxy();
00083
00089 SI_Error Connect( CdotXSITemplate *in_pTemplate, SI_Long in_lArrayIndex );
00090
00097 inline SI_Long GetUsed() const;
00098
00104 inline SI_Long GetSize() const;
00105
00110 inline SI_Long UsedMem() const;
00111
00116 inline SI_Long AllocatedMem() const;
00117
00129 SI_Long Reserve( const SI_Long in_lNbElem );
00130
00146 SI_Long Resize( const SI_Long in_lNewNbElem );
00147
00162 SI_Long Extend( const SI_Long in_lNbElem );
00163
00180 SI_Long InsertAt(const SI_Long in_lIndex, const SI_Long in_lNbElem);
00181
00191 inline SI_Long Add(CElemType in_Elem);
00192
00197 SI_Void DeleteAt(const SI_Long in_lIndex, const SI_Long in_lNbElem);
00198
00203 inline CElemType & operator [] ( const SI_Long in_lIndex ) const;
00204
00209 inline CElemType & operator [] ( const SI_Long in_lIndex );
00210
00219 SI_Long Pack( SI_Long i_lMaxWasted = 4L );
00220
00224 SI_Void DisposeData();
00225
00231 SI_Int Copy( const CSIBCArray<CElemType>& in_rSrcObject );
00232
00238 SI_Int Copy( const CSLArrayProxy<CElemType, CSubElemType, StructSize>& in_rSrcObject );
00239
00245 CSLArrayProxy& operator = ( const CSIBCArray<CElemType>& in_rSrcObject );
00246
00252 CSLArrayProxy& operator = ( const CSLArrayProxy<CElemType, CSubElemType, StructSize>& in_rSrcObject );
00253
00257 inline CElemType* ArrayPtr();
00258
00264 inline SI_Void Set( SI_Long start, SI_Long in_lNbElem, CElemType value );
00265
00266 private :
00267 SI_Long m_lNbUsedElem;
00268 SI_Long m_lNbAllocElem;
00269
00270 SI_TinyVariant *m_pVariant;
00271
00272 SI_Long ExpandArray
00273 (
00274 const SI_Long in_lNewSize,
00275 const SI_Long in_lExpandRatio = 1
00276 );
00277 };
00278
00280
00281
00282 template <class CElemType, class CSubElemType, SI_Int StructSize>
00283 CSLArrayProxy<CElemType, CSubElemType, StructSize>::CSLArrayProxy
00284 (
00285 CdotXSITemplate *in_pTemplate,
00286 SI_Long in_lArrayIndex
00287 )
00288 {
00289 Connect(in_pTemplate, in_lArrayIndex);
00290 }
00291
00292 template <class CElemType, class CSubElemType, SI_Int StructSize>
00293 CSLArrayProxy<CElemType, CSubElemType, StructSize>::CSLArrayProxy
00294 (
00295 )
00296 {
00297 }
00298
00299 template <class CElemType, class CSubElemType, SI_Int StructSize>
00300 CSLArrayProxy<CElemType, CSubElemType, StructSize>::~CSLArrayProxy()
00301 {
00302 }
00303
00304 template <class CElemType, class CSubElemType, SI_Int StructSize>
00305 SI_Error CSLArrayProxy<CElemType, CSubElemType, StructSize>::Connect
00306 (
00307 CdotXSITemplate *in_pTemplate,
00308 SI_Long in_lArrayIndex
00309 )
00310 {
00311
00312 _SI_ASSERT(in_pTemplate);
00313 CdotXSIParam *l_pParam = in_pTemplate->Params().Item( in_lArrayIndex );
00314
00315 if ( !l_pParam )
00316 return SI_SUCCESS;
00317
00318 _SI_ASSERT(l_pParam);
00319 m_pVariant = l_pParam->GetVariantPtr();
00320
00321
00322 _SI_ASSERT(m_pVariant);
00323
00324 if(m_pVariant->p_voidVal == NULL)
00325 {
00326 m_pVariant->numElems = 0;
00327 }
00328
00329 m_lNbUsedElem = m_pVariant->numElems / StructSize;
00330 m_lNbAllocElem = m_lNbUsedElem;
00331
00332 return SI_SUCCESS;
00333 }
00334
00335 template <class CElemType, class CSubElemType, SI_Int StructSize>
00336 inline SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::GetUsed() const
00337 {
00338 return m_lNbUsedElem;
00339 }
00340
00341 template <class CElemType, class CSubElemType, SI_Int StructSize>
00342 inline SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::GetSize() const
00343 {
00344 return m_lNbAllocElem;
00345 }
00346
00347 template <class CElemType, class CSubElemType, SI_Int StructSize>
00348 inline SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::UsedMem() const
00349 {
00350 return GetUsed() * StructSize;
00351 }
00352
00353 template <class CElemType, class CSubElemType, SI_Int StructSize>
00354 inline SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::AllocatedMem() const
00355 {
00356 return GetSize() * StructSize;
00357 }
00358
00359 template <class CElemType, class CSubElemType, SI_Int StructSize>
00360 SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::Reserve
00361 (
00362 const SI_Long in_lNbElem
00363 )
00364 {
00365 return ExpandArray(in_lNbElem);
00366 }
00367
00368 template <class CElemType, class CSubElemType, SI_Int StructSize>
00369 SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::Resize
00370 (
00371 const SI_Long in_lNewNbElem
00372 )
00373 {
00374 return ExpandArray( in_lNewNbElem, 2 );
00375 }
00376
00377 template <class CElemType, class CSubElemType, SI_Int StructSize>
00378 SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::Extend
00379 (
00380 const SI_Long in_lNbElem
00381 )
00382 {
00383 return Resize( m_lNbUsedElem + in_lNbElem );
00384 }
00385
00386 template <class CElemType, class CSubElemType, SI_Int StructSize>
00387 SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::InsertAt
00388 (
00389 const SI_Long in_lIndex,
00390 const SI_Long in_lNbElem
00391 )
00392 {
00393 _SI_ASSERT(in_lNbElem);
00394
00395 SI_Long l_lOldNb = m_lNbUsedElem;
00396 SI_Long l_lNb = m_lNbUsedElem + in_lNbElem;
00397 SI_Long l_lInsert = in_lIndex;
00398
00399
00400 if (l_lInsert > m_lNbUsedElem)
00401 l_lInsert = m_lNbUsedElem;
00402
00403
00404 Reserve( l_lNb );
00405
00406 if (l_lOldNb > in_lIndex)
00407 {
00408 CElemType *l_pDest = ((CElemType*)m_pVariant->p_voidVal) + (in_lIndex + in_lNbElem);
00409 CElemType *l_pSrc = ((CElemType*)m_pVariant->p_voidVal) + in_lIndex;
00410
00411 memmove( l_pDest, l_pSrc, (l_lOldNb - in_lIndex) * sizeof(CSubElemType) * StructSize);
00412 }
00413
00414 m_pVariant->numElems = m_lNbUsedElem * StructSize;
00415 return m_lNbUsedElem;
00416 }
00417
00418 template <class CElemType, class CSubElemType, SI_Int StructSize>
00419 SI_Void CSLArrayProxy<CElemType, CSubElemType, StructSize>::DeleteAt
00420 (
00421 const SI_Long in_lIndex,
00422 const SI_Long in_lNbElem
00423 )
00424 {
00425 _SI_ASSERT(in_lNbElem);
00426 SI_Long l_lToDelete = in_lNbElem;
00427
00428 if ( l_lToDelete > m_lNbUsedElem )
00429 l_lToDelete = m_lNbUsedElem;
00430
00431 if ((in_lIndex + in_lNbElem) < m_lNbUsedElem )
00432 {
00433 CElemType *l_pSrc = ((CElemType*)m_pVariant->p_voidVal) + in_lIndex + in_lNbElem;
00434 CElemType *l_pDest= ((CElemType*)m_pVariant->p_voidVal) + in_lIndex ;
00435 CElemType *l_pEnd = ((CElemType*)m_pVariant->p_voidVal) + m_lNbUsedElem;
00436
00437 memmove( l_pDest, l_pSrc, (l_pEnd - l_pSrc) * sizeof(CSubElemType) * StructSize);
00438 }
00439
00440 m_lNbUsedElem = m_lNbUsedElem - l_lToDelete;
00441 m_pVariant->numElems = m_lNbUsedElem * StructSize;
00442 }
00443
00444 template <class CElemType, class CSubElemType, SI_Int StructSize>
00445 inline CElemType& CSLArrayProxy<CElemType, CSubElemType, StructSize>::operator []
00446 (
00447 const SI_Long in_lIndex
00448 ) const
00449 {
00450 _SI_ASSERT(in_lIndex < ((SI_Long)m_lNbUsedElem));
00451 _SI_ASSERT(in_lIndex >= 0);
00452
00453 return *( ( (CElemType*) m_pVariant->p_voidVal ) + in_lIndex);
00454 }
00455
00456 template <class CElemType, class CSubElemType, SI_Int StructSize>
00457 inline CElemType& CSLArrayProxy<CElemType, CSubElemType, StructSize>::operator []
00458 (
00459 const SI_Long in_lIndex
00460 )
00461 {
00462 _SI_ASSERT(in_lIndex < ((SI_Long)m_lNbUsedElem));
00463 _SI_ASSERT(in_lIndex >= 0);
00464
00465 return *( ( (CElemType*) m_pVariant->p_voidVal ) + in_lIndex);
00466 }
00467
00468 template <class CElemType, class CSubElemType, SI_Int StructSize>
00469 SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::Pack
00470 (
00471 SI_Long i_lMaxWasted
00472 )
00473 {
00474
00475 if (( m_lNbAllocElem - m_lNbUsedElem ) > i_lMaxWasted )
00476 {
00477
00478 CElemType * l_pNewArray = (CElemType *) FTK_calloc( m_lNbUsedElem * StructSize, sizeof( CSubElemType )) ;
00479
00480
00481 if ( l_pNewArray != NULL )
00482 {
00483
00484 CElemType *l_pCurrentArray = (CElemType*)m_pVariant->p_voidVal;
00485 register SI_Long i;
00486
00487 for ( i = 0; i < GetUsed(); i++)
00488 {
00489 l_pNewArray[i] = l_pCurrentArray[i];
00490 }
00491
00492
00493 for ( i = 0; i < GetUsed(); i++)
00494 {
00495 l_pCurrentArray[i].~CElemType();
00496 }
00497 FTK_free((void *) l_pCurrentArray );
00498
00499
00500 m_pVariant->p_voidVal = l_pNewArray;
00501
00502
00503 m_lNbAllocElem = m_lNbUsedElem;
00504 m_pVariant->numElems = m_lNbUsedElem * StructSize;
00505 }
00506 }
00507
00508 return m_lNbUsedElem;
00509 }
00510
00511 template <class CElemType, class CSubElemType, SI_Int StructSize>
00512 SI_Void CSLArrayProxy<CElemType, CSubElemType, StructSize>::DisposeData
00513 ()
00514 {
00515 CElemType *l_pCurrentArray = (CElemType*)m_pVariant->p_voidVal;
00516 for (register SI_Long i = 0; i < m_lNbAllocElem; i++ )
00517 {
00518 l_pCurrentArray[i].~CElemType();
00519 }
00520 FTK_free( (void *) m_pVariant->p_voidVal );
00521 m_lNbAllocElem = 0; m_lNbUsedElem = 0;
00522 m_pVariant->numElems = 0;
00523
00524 Reserve(1);
00525 }
00526
00527 template <class CElemType, class CSubElemType, SI_Int StructSize>
00528 SI_Int CSLArrayProxy<CElemType, CSubElemType, StructSize>::Copy
00529 (
00530 const CSIBCArray<CElemType>& in_rSrcObject
00531 )
00532 {
00533 DisposeData();
00534
00535 if (in_rSrcObject.GetUsed() > 0)
00536 {
00537
00538 Reserve( in_rSrcObject.GetUsed() );
00539
00540
00541 if (m_lNbUsedElem >= in_rSrcObject.GetUsed())
00542 {
00543 CElemType *l_pDestinationArray = (CElemType*)m_pVariant->p_voidVal;
00544
00545
00546 for ( register SI_Long i = 0; i < m_lNbUsedElem; i++)
00547 {
00548 l_pDestinationArray[i] = in_rSrcObject[i];
00549 }
00550
00551
00552 return m_lNbUsedElem;
00553 }
00554 }
00555
00556 return 0;
00557 }
00558
00559 template <class CElemType, class CSubElemType, SI_Int StructSize>
00560 SI_Int CSLArrayProxy<CElemType, CSubElemType, StructSize>::Copy
00561 (
00562 const CSLArrayProxy<CElemType, CSubElemType, StructSize>& in_rSrcObject
00563 )
00564 {
00565 DisposeData();
00566
00567 if (in_rSrcObject.GetUsed() > 0)
00568 {
00569
00570 Reserve( in_rSrcObject.GetUsed() );
00571
00572
00573 if (m_lNbUsedElem >= in_rSrcObject.GetUsed())
00574 {
00575 CElemType *l_pDestinationArray = (CElemType*)m_pVariant->p_voidVal;
00576
00577
00578 for ( register SI_Long i = 0; i < m_lNbUsedElem; i++)
00579 {
00580 l_pDestinationArray[i] = in_rSrcObject[i];
00581 }
00582
00583
00584 return m_lNbUsedElem;
00585 }
00586 }
00587
00588 return 0;
00589 }
00590
00591 template <class CElemType, class CSubElemType, SI_Int StructSize>
00592 CSLArrayProxy<CElemType, CSubElemType, StructSize>& CSLArrayProxy<CElemType, CSubElemType, StructSize>::operator =
00593 (
00594 const CSIBCArray<CElemType>& in_rSrcObject
00595 )
00596 {
00597 Copy(in_rSrcObject);
00598 return *this;
00599 }
00600
00601 template <class CElemType, class CSubElemType, SI_Int StructSize>
00602 CSLArrayProxy<CElemType, CSubElemType, StructSize>& CSLArrayProxy<CElemType, CSubElemType, StructSize>::operator =
00603 (
00604 const CSLArrayProxy<CElemType, CSubElemType, StructSize>& in_rSrcObject
00605 )
00606 {
00607 Copy(in_rSrcObject);
00608 return *this;
00609 }
00610
00611 template <class CElemType, class CSubElemType, SI_Int StructSize>
00612 inline CElemType* CSLArrayProxy<CElemType, CSubElemType, StructSize>::ArrayPtr()
00613 {
00614 return (CElemType*)m_pVariant->p_voidVal;
00615 }
00616
00617 template <class CElemType, class CSubElemType, SI_Int StructSize>
00618 inline SI_Void CSLArrayProxy<CElemType, CSubElemType, StructSize>::Set
00619 (
00620 SI_Long in_lstart,
00621 SI_Long in_lNbElem,
00622 CElemType in_Value
00623 )
00624 {
00625 SI_Long l_lEnd = in_lstart + in_lNbElem;
00626
00627 if ( l_lEnd > m_lNbUsedElem )
00628 {
00629 l_lEnd = m_lNbUsedElem;
00630 }
00631
00632 CElemType* l_pArrayToSet = (CElemType*)m_pVariant->p_voidVal;
00633 for ( register SI_Long i = in_lstart; i < l_lEnd; i++ )
00634 {
00635 l_pArrayToSet[i] = in_Value;
00636 }
00637 }
00638
00645 template <class CElemType, class CSubElemType, SI_Int StructSize>
00646 SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::ExpandArray
00647 (
00648 const SI_Long in_lNewSize,
00649 const SI_Long in_lExpandRatio
00650 )
00651 {
00652
00653 if ( GetSize() >= in_lNewSize )
00654 {
00655 m_lNbUsedElem = in_lNewSize;
00656 m_pVariant->numElems = m_lNbUsedElem * StructSize;
00657
00658 return m_lNbUsedElem;
00659 }
00660
00661 else
00662 {
00663
00664 SI_Long l_lNewArraySize = in_lNewSize * in_lExpandRatio;
00665
00666
00667 CElemType * l_pNewArray = (CElemType *) FTK_calloc( sizeof( CSubElemType), l_lNewArraySize * StructSize );
00668
00669 if (l_pNewArray)
00670 {
00671
00672 CElemType *l_pCurrentArray = (CElemType*)m_pVariant->p_voidVal;
00673 register SI_Long i;
00674
00675 for ( i = 0; i < GetUsed(); i++)
00676 {
00677 l_pNewArray[i] = l_pCurrentArray[i];
00678 }
00679 for ( i = GetUsed(); i< l_lNewArraySize; i++)
00680 {
00681 ::new((void*)&l_pNewArray[i]) CElemType;
00682 }
00683
00684
00685 for ( i = 0; i < GetUsed(); i++)
00686 {
00687 l_pCurrentArray[i].~CElemType();
00688 }
00689
00690 FTK_free((void *) l_pCurrentArray );
00691
00692 m_pVariant->p_voidVal = l_pNewArray;
00693
00694
00695 m_pVariant->numElems = in_lNewSize * StructSize;
00696
00697
00698 m_lNbAllocElem = l_lNewArraySize;
00699
00700 return m_lNbUsedElem = in_lNewSize;
00701 }
00702 }
00703
00704
00705 return m_lNbUsedElem;
00706 }
00707
00708 template <class CElemType, class CSubElemType, SI_Int StructSize>
00709 inline SI_Long CSLArrayProxy<CElemType, CSubElemType, StructSize>::Add
00710 (
00711 CElemType in_Elem
00712 )
00713 {
00714 Extend(1);
00715 (*this)[m_lNbUsedElem - 1] = in_Elem;
00716 return m_lNbUsedElem;
00717 }
00718
00719 #if defined(_WIN32) || defined(_WIN32_WCE) || defined(_XBOX)
00720 #pragma pack(pop)
00721 #elif defined (CODEWARRIOR)
00722 #pragma options align= reset
00723 #endif
00724
00725 #endif // __SL_ARRAY_H__