xsi_indexset.h Source File
 
 
 
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__