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