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
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
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;
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__