xsi_indexset.h
Go to the documentation of this file.

    00001 //*****************************************************************************
    00011 //*****************************************************************************
    00012
    00013 #if (_MSC_VER > 1000) || defined(SGI_COMPILER)
    00014 #pragma once
    00015 #endif
    00016
    00017 #ifndef __XSIINDEXSET_H__
    00018 #define __XSIINDEXSET_H__
    00019
    00020 #include <sicppsdk.h>
    00021 #include <xsi_icenodecontext.h>
    00022
    00023 namespace XSI {
    00024
    00025 static const char kRevLogTable256[] =
    00026 {
    00027   8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00028   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00029   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00030   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00031   6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00032   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00033   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00034   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00035   7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00036   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00037   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00038   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00039   6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00040   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00041   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    00042   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
    00043 };
    00044
    00045 const LONG kBitShift= 5;
    00046 const LONG kBitSize = 32;
    00047
    00048 class CBitsetHelper
    00049 {
    00050     public:
    00051     SICPPSDK_INLINE CBitsetHelper( );
    00052
    00053     SICPPSDK_INLINE LONG& GetCountRef( );
    00054     SICPPSDK_INLINE LONG GetCount( ) const;
    00055     SICPPSDK_INLINE ULONG*& GetArrayRef();
    00056
    00057     SICPPSDK_INLINE bool GetNextBit( LONG& in_index) const;
    00058     SICPPSDK_INLINE CStatus SetBit( LONG in_index, bool in_bVal );
    00059     SICPPSDK_INLINE bool GetBit( LONG in_index ) const;
    00060     SICPPSDK_INLINE void Clear( );
    00061
    00062     SICPPSDK_INLINE CBitsetHelper& operator = ( const CBitsetHelper& in_bitset );
    00063
    00064 private:
    00065     SICPPSDK_INLINE LONG GetNextBitInternal(LONG& in_index) const;
    00066     SICPPSDK_INLINE LONG GetFirstBit( ULONG in_nVal) const;
    00067     SICPPSDK_INLINE LONG GetRevLogBase2( ULONG in_nVal ) const;
    00068     SICPPSDK_INLINE CStatus SetBit( LONG in_index );
    00069     SICPPSDK_INLINE CStatus ClearBit( LONG in_index );
    00070
    00071     LONG    m_nCount;
    00072     ULONG*  m_pArray;
    00073 };
    00074
    00075 //*****************************************************************************
    00120 //*****************************************************************************
    00121
    00122 class CIndexSet
    00123 {
    00124 public:
    00125     typedef CIndexSet* PtrType;
    00126
    00127     enum StorageMode
    00128     {
    00129         Range,
    00130         Bitset,
    00131         Indices,
    00132         Unknown
    00133     };
    00134
    00135     //*****************************************************************************
    00143     //*****************************************************************************
    00144     class Iterator
    00145     {
    00146         public:
    00147         friend class CIndexSet;
    00148
    00153         SICPPSDK_INLINE void Remove();
    00154
    00158         SICPPSDK_INLINE bool HasNext() const;
    00159
    00163         SICPPSDK_INLINE ULONG GetIndex() const;
    00164
    00168         SICPPSDK_INLINE ULONG GetAbsoluteIndex() const;
    00169
    00172         SICPPSDK_INLINE void Next();
    00173
    00177         SICPPSDK_INLINE operator ULONG () const;
    00178
    00179         private:
    00180         SICPPSDK_INLINE Iterator( PtrType in_pSet );
    00181
    00182         bool    m_bEnd;
    00183         LONG    m_nPos;
    00184         PtrType m_pSet;
    00185     };
    00186
    00187     friend class ICENodeContext;
    00188     friend class Iterator;
    00189
    00193     SICPPSDK_INLINE CIndexSet( const ICENodeContext& in_ctxt );
    00194
    00203     SICPPSDK_INLINE CIndexSet( const ICENodeContext& in_ctxt, ULONG in_nInputPortID, ULONG in_nInstanceIndex=0 ) ;
    00204
    00207     SICPPSDK_INLINE ~CIndexSet();
    00208
    00212     SICPPSDK_INLINE Iterator Begin();
    00213
    00216     SICPPSDK_INLINE ULONG GetFilteredCount() const;
    00217
    00218     protected:
    00219     SICPPSDK_INLINE void            RemoveElement( Iterator& io_it );
    00220     SICPPSDK_INLINE bool            GetNextBit(LONG& in_it) const;
    00221     SICPPSDK_INLINE ULONG*&         GetDataRef();
    00222     SICPPSDK_INLINE ULONG&          GetIndexOffsetRef();
    00223     SICPPSDK_INLINE void*&          GetHandleRef();
    00224     SICPPSDK_INLINE ULONG&          GetCountRef();
    00225     SICPPSDK_INLINE StorageMode&    GetStorageModeRef();
    00226     SICPPSDK_INLINE ICENodeContext& GetContextRef();
    00227     SICPPSDK_INLINE CBitsetHelper&  GetBitsetRef();
    00228
    00229     ULONG*          m_pData;
    00230     ULONG           m_nIndexOffset;
    00231     void*           m_pHandle;
    00232     ULONG           m_nCount;
    00233     StorageMode     m_eStorageMode;
    00234     ICENodeContext  m_ctxt;
    00235     CBitsetHelper   m_bitset;
    00236 };
    00237
    00238 SICPPSDK_INLINE CIndexSet::CIndexSet( const ICENodeContext& in_ctxt )
    00239 {
    00240     m_ctxt = in_ctxt;
    00241     m_eStorageMode = Unknown;
    00242     m_nIndexOffset = 0;
    00243     m_pHandle = NULL;
    00244     m_pData = NULL;
    00245     m_nCount = 0;
    00246     m_pData = NULL;
    00247
    00248     m_ctxt.AcquireIndexSet( *this );
    00249 }
    00250
    00251 SICPPSDK_INLINE CIndexSet::CIndexSet( const ICENodeContext& in_ctxt, ULONG in_nInputPortID, ULONG in_nInstanceIndex )
    00252 {
    00253     m_ctxt = in_ctxt;
    00254     m_eStorageMode = Unknown;
    00255     m_nIndexOffset = 0;
    00256     m_pHandle = NULL;
    00257     m_pData = NULL;
    00258     m_nCount = 0;
    00259     m_pData = NULL;
    00260
    00261     m_ctxt.AcquireIndexSetFromPort( *this, in_nInputPortID, in_nInstanceIndex );
    00262 }
    00263
    00264 SICPPSDK_INLINE CIndexSet::~CIndexSet()
    00265 {
    00266     m_ctxt.ReleaseIndexSet( *this );
    00267 }
    00268
    00269 SICPPSDK_INLINE CIndexSet::Iterator CIndexSet::Begin()
    00270 {
    00271     return CIndexSet::Iterator((PtrType)this);
    00272 }
    00273
    00274 SICPPSDK_INLINE ULONG CIndexSet::GetFilteredCount() const
    00275 {
    00276     ULONG l_ulCount = 0;
    00277     m_ctxt.GetFilteredCountFromIndexSet( *this, l_ulCount );
    00278
    00279     return l_ulCount;
    00280 }
    00281
    00282 SICPPSDK_INLINE void CIndexSet::RemoveElement( CIndexSet::Iterator& io_it )
    00283 {
    00284     m_ctxt.RemoveElementFromIndexSet( *this, io_it.m_nPos, io_it.m_nPos, io_it.m_bEnd );
    00285 }
    00286
    00287 SICPPSDK_INLINE bool CIndexSet::GetNextBit(LONG& in_it) const
    00288 {
    00289     if ( m_eStorageMode != Bitset )
    00290     {
    00291         assert(false);
    00292         return false;
    00293     }
    00294
    00295     return m_bitset.GetNextBit( in_it );
    00296 }
    00297
    00298 SICPPSDK_INLINE ULONG*& CIndexSet::GetDataRef()
    00299 {
    00300     return m_pData;
    00301 }
    00302
    00303 SICPPSDK_INLINE ULONG& CIndexSet::GetIndexOffsetRef()
    00304 {
    00305     return m_nIndexOffset;
    00306 }
    00307
    00308 SICPPSDK_INLINE void*& CIndexSet::GetHandleRef()
    00309 {
    00310     return m_pHandle;
    00311 }
    00312
    00313 SICPPSDK_INLINE ULONG& CIndexSet::GetCountRef()
    00314 {
    00315     return m_nCount;
    00316 }
    00317
    00318 SICPPSDK_INLINE CIndexSet::StorageMode& CIndexSet::GetStorageModeRef()
    00319 {
    00320     return m_eStorageMode;
    00321 }
    00322
    00323 SICPPSDK_INLINE ICENodeContext& CIndexSet::GetContextRef()
    00324 {
    00325     return m_ctxt;
    00326 }
    00327
    00328 SICPPSDK_INLINE CBitsetHelper& CIndexSet::GetBitsetRef()
    00329 {
    00330     return m_bitset;
    00331 }
    00332
    00333 SICPPSDK_INLINE CIndexSet::Iterator::Iterator( CIndexSet::PtrType in_pSet ) :
    00334     m_bEnd(false),
    00335     m_nPos(-1),
    00336     m_pSet(in_pSet)
    00337 {
    00338     Next();
    00339 }
    00340
    00341 // Goto next element
    00342 SICPPSDK_INLINE void CIndexSet::Iterator::Next()
    00343 {
    00344     switch(m_pSet->m_eStorageMode)
    00345     {
    00346         case Range:
    00347             m_bEnd = (ULONG)(++m_nPos) == m_pSet->m_nCount;
    00348             break;
    00349         case Bitset:
    00350             m_bEnd = !m_pSet->GetNextBit(m_nPos);
    00351             break;
    00352         case Indices:
    00353             while(true)
    00354             {
    00355                 ++m_nPos;
    00356                 if ((ULONG)m_nPos == m_pSet->m_nCount)
    00357                 {
    00358                     m_bEnd = true;
    00359                     break;
    00360                 }
    00361
    00362                 if(m_pSet->m_pData[m_nPos] != UINT_MAX)
    00363                 {
    00364                     break;
    00365                 }
    00366             }
    00367             break;
    00368         default:
    00369             break;
    00370     };
    00371 }
    00372
    00373 SICPPSDK_INLINE ULONG CIndexSet::Iterator::GetIndex() const
    00374 {
    00375     switch(m_pSet->m_eStorageMode)
    00376     {
    00377         case Indices:
    00378             return m_pSet->m_pData[m_nPos];
    00379         default:
    00380             return m_nPos;
    00381     }
    00382 }
    00383
    00384 SICPPSDK_INLINE ULONG CIndexSet::Iterator::GetAbsoluteIndex() const
    00385 {
    00386     return GetIndex() + m_pSet->m_nIndexOffset;
    00387 }
    00388
    00389 SICPPSDK_INLINE CIndexSet::Iterator::operator ULONG () const
    00390 {
    00391     return GetIndex( );
    00392 }
    00393
    00394 SICPPSDK_INLINE bool CIndexSet::Iterator::HasNext() const
    00395 {
    00396     return m_bEnd == false && m_pSet->m_nCount > 0;
    00397 }
    00398
    00399 SICPPSDK_INLINE void CIndexSet::Iterator::Remove()
    00400 {
    00401     if (m_bEnd )
    00402     {
    00403         return;
    00404     }
    00405
    00406     m_pSet->RemoveElement( *this );
    00407 }
    00408
    00409 // CBitsetHelper
    00410 SICPPSDK_INLINE CBitsetHelper::CBitsetHelper( ) : m_nCount(UINT_MAX), m_pArray(NULL) {}
    00411
    00412 SICPPSDK_INLINE void CBitsetHelper::Clear( )
    00413 {
    00414     m_nCount = 0;
    00415     m_pArray = 0;
    00416 }
    00417
    00418 SICPPSDK_INLINE CBitsetHelper& CBitsetHelper::operator = ( const CBitsetHelper& in_bitset )
    00419 {
    00420     m_nCount = in_bitset.m_nCount;
    00421     m_pArray = in_bitset.m_pArray;
    00422     return *this;
    00423 }
    00424
    00425 SICPPSDK_INLINE LONG& CBitsetHelper::GetCountRef( )
    00426 {
    00427     return m_nCount;
    00428 }
    00429
    00430 SICPPSDK_INLINE LONG CBitsetHelper::GetCount( ) const
    00431 {
    00432     return m_nCount;
    00433 }
    00434
    00435 SICPPSDK_INLINE ULONG*& CBitsetHelper::GetArrayRef()
    00436 {
    00437     return m_pArray;
    00438 }
    00439
    00440 SICPPSDK_INLINE bool CBitsetHelper::GetNextBit( LONG& in_it ) const
    00441 {
    00442     return ( in_it = GetNextBitInternal( in_it ) ) != m_nCount;
    00443 }
    00444
    00445 SICPPSDK_INLINE bool CBitsetHelper::GetBit( LONG in_index ) const
    00446 {
    00447     if ( !m_pArray )
    00448     {
    00449         return false;
    00450     }
    00451
    00452     return ( m_pArray[ in_index >> kBitShift ] & ( 1 << ( in_index % kBitSize ) ) ) != 0;
    00453 }
    00454
    00455 SICPPSDK_INLINE CStatus CBitsetHelper::SetBit( LONG in_index, bool in_bVal )
    00456 {
    00457     if ( in_bVal )
    00458     {
    00459         SetBit( in_index );
    00460     }
    00461     else
    00462     {
    00463         ClearBit( in_index );
    00464     }
    00465     return CStatus::OK;
    00466 }
    00467
    00468 SICPPSDK_INLINE CStatus CBitsetHelper::SetBit( LONG in_index )
    00469 {
    00470     if ( !m_pArray )
    00471     {
    00472         return CStatus::AccessDenied;
    00473     }
    00474
    00475     m_pArray[ in_index >> kBitShift ] |= ( 1 << ( in_index % kBitSize ) );
    00476     return CStatus::OK;
    00477 }
    00478
    00479 SICPPSDK_INLINE CStatus CBitsetHelper::ClearBit( LONG in_index )
    00480 {
    00481     if ( !m_pArray )
    00482     {
    00483         return CStatus::AccessDenied;
    00484     }
    00485
    00486     m_pArray[ in_index >> kBitShift ] &= ~( 1 << ( in_index % kBitSize ) );
    00487     return CStatus::OK;
    00488 }
    00489
    00490 SICPPSDK_INLINE LONG CBitsetHelper::GetNextBitInternal( LONG& in_index ) const
    00491 {
    00492     LONG nCurrentBit = in_index+1;
    00493     if (nCurrentBit >= m_nCount)
    00494     {
    00495         return m_nCount;
    00496     }
    00497
    00498     LONG nCurrentIdx = nCurrentBit >> kBitShift;
    00499
    00500     ULONG nVal = m_pArray[nCurrentIdx];
    00501     nVal >>= (nCurrentBit - (nCurrentIdx << kBitShift));
    00502
    00503     LONG nDeltaBit;
    00504     if ((nDeltaBit = GetFirstBit(nVal)) == 32)
    00505     {
    00506         LONG nMaxIdx = ((m_nCount-1)>>kBitShift)+1;
    00507
    00508         for( nCurrentIdx++; nCurrentIdx != nMaxIdx; nCurrentIdx++ )
    00509         {
    00510             nDeltaBit = GetFirstBit(m_pArray[nCurrentIdx]);
    00511
    00512             if(nDeltaBit != 32)
    00513             {
    00514                 break;
    00515             }
    00516         }
    00517
    00518         if( nCurrentIdx == nMaxIdx )
    00519         {
    00520             return m_nCount;
    00521         }
    00522         else
    00523         {
    00524             nCurrentBit = ( nCurrentIdx << kBitShift ) + nDeltaBit;
    00525         }
    00526     }
    00527     else
    00528     {
    00529         nCurrentBit += nDeltaBit;
    00530     }
    00531
    00532     if( nCurrentBit > m_nCount )
    00533     {
    00534         return m_nCount;
    00535     }
    00536
    00537     return nCurrentBit;
    00538 }
    00539
    00540 SICPPSDK_INLINE LONG CBitsetHelper::GetFirstBit( ULONG in_nVal ) const
    00541 {
    00542     return GetRevLogBase2( in_nVal );
    00543 }
    00544
    00545 SICPPSDK_INLINE LONG CBitsetHelper::GetRevLogBase2( ULONG in_nVal ) const
    00546 {
    00547     register unsigned int t, tt; // temporaries
    00548
    00549     if ( tt = in_nVal & 0xFFFF, tt != 0 )
    00550     {
    00551       return (t = in_nVal & 0xFF, t != 0 ) ? kRevLogTable256[t] : 8 + kRevLogTable256[tt >> 8];
    00552     }
    00553     else
    00554     {
    00555       return (t = in_nVal & 0x00FF0000, t != 0 ) ? 16 + kRevLogTable256[t >> 16] : 24 + kRevLogTable256[in_nVal >> 24];
    00556     }
    00557 }
    00558
    00559 };
    00560
    00561 #endif // __XSIINDEXSET_H__