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