687 lines
18 KiB
C++
687 lines
18 KiB
C++
// Copyright (C) 1997 Microsoft Corporation. All rights reserved.
|
|
|
|
#include "header.h"
|
|
|
|
#ifndef HHCTRL
|
|
#include "hha_strtable.h"
|
|
#endif
|
|
|
|
#ifdef HHCTRL
|
|
#include "strtable.h"
|
|
#include "secwin.h"
|
|
#endif
|
|
|
|
#include "system.h"
|
|
#include "csubset.h"
|
|
#include "ctable.h"
|
|
|
|
const char g_szUDSKey[] = "ssv2\\UDS"; // User Defined Subsets
|
|
|
|
|
|
// Shared init.
|
|
//
|
|
void CSubSets::_CSubSets(void)
|
|
{
|
|
m_max_subsets = MAX_SUBSETS;
|
|
m_aSubSets = (CSubSet**)lcCalloc( m_max_subsets * sizeof( CSubSet* ) );
|
|
m_cur_Set = NULL;
|
|
m_Toc = NULL;
|
|
m_Index = NULL;
|
|
m_FTS = NULL;
|
|
m_cSets = 0;
|
|
m_pszFilename = NULL;
|
|
}
|
|
|
|
#ifdef HHCTRL
|
|
|
|
CSubSets::CSubSets(int ITSize, CHmData* const phmData, BOOL fPredefined=FALSE ) : CSubSet(ITSize)
|
|
{
|
|
_CSubSets();
|
|
m_fPredefined = fPredefined;
|
|
m_bPredefined = fPredefined;
|
|
m_pIT = new CInfoType();
|
|
m_pIT->CopyTo(phmData);
|
|
}
|
|
|
|
#endif
|
|
|
|
CSubSets::CSubSets( int ITSize = 4, CInfoType *pIT=NULL, BOOL fPredefined=FALSE ) : CSubSet( ITSize)
|
|
{
|
|
_CSubSets();
|
|
m_fPredefined = fPredefined;
|
|
m_bPredefined = fPredefined;
|
|
m_pIT = new CInfoType();
|
|
if ( pIT != NULL )
|
|
*m_pIT = *pIT; // BUGBUG: This will fault if you ever use the defult for the parameter.
|
|
}
|
|
|
|
CSubSets::CSubSets( int ITSize, CTable *ptblSubSets, CSiteMap *pSiteMap, BOOL fPredefined=FALSE ) : CSubSet(ITSize)
|
|
{
|
|
_CSubSets();
|
|
m_fPredefined = fPredefined;
|
|
m_bPredefined = fPredefined;
|
|
m_pIT = new CInfoType();
|
|
if ( pSiteMap )
|
|
*m_pIT = *pSiteMap;
|
|
|
|
// populate subsets with declarations in ptblSubSets
|
|
CStr cszSSDecl; // one item of a subset
|
|
CStr cszSubSetName;
|
|
CStr cszITName;
|
|
int cDeclarations = ptblSubSets->CountStrings();
|
|
|
|
for (int i=1; i<cDeclarations; i++ )
|
|
{
|
|
cszSSDecl = ptblSubSets->GetPointer( i );
|
|
|
|
int type ;
|
|
if ( isSameString(cszSSDecl.psz, txtSSInclusive) )
|
|
type = SS_INCLUSIVE;
|
|
else if ( isSameString(cszSSDecl.psz, txtSSExclusive) )
|
|
type = SS_EXCLUSIVE;
|
|
|
|
cszSubSetName = StrChr(cszSSDecl.psz, ':')+1;
|
|
PSTR psz = StrChr(cszSubSetName, ':');
|
|
*psz = '\0';
|
|
cszITName = StrChr( cszSSDecl.psz, ':')+1;
|
|
|
|
if ( GetSubSetIndex( cszSubSetName ) < 0 )
|
|
{
|
|
AddSubSet(); // create a new subset
|
|
m_cur_Set->m_cszSubSetName = cszSubSetName.psz;
|
|
m_cur_Set->m_bPredefined = TRUE;
|
|
}
|
|
|
|
int pos = m_pIT->m_itTables.m_ptblInfoTypes->IsStringInTable( cszITName.psz );
|
|
if ( pos <= 0 )
|
|
continue;
|
|
if ( type == SS_INCLUSIVE )
|
|
m_cur_Set->AddIncType( pos ); // Add this "include" bit.
|
|
else
|
|
m_cur_Set->AddExcType( pos ); // Add this "exclude" bit.
|
|
}
|
|
}
|
|
|
|
|
|
CSubSets::~CSubSets()
|
|
{
|
|
if (m_aSubSets) //leak fix
|
|
{
|
|
for(int i=0; i<m_max_subsets; i++)
|
|
{
|
|
if ( m_aSubSets[i] )
|
|
delete m_aSubSets[i];
|
|
}
|
|
lcFree(m_aSubSets);
|
|
}
|
|
|
|
if ( m_pszFilename )
|
|
lcFree(m_pszFilename );
|
|
|
|
if ( m_pIT )
|
|
delete( m_pIT );
|
|
}
|
|
|
|
const CSubSets& CSubSets::operator=( const CSubSets& SetsSrc ) // Copy Constructor
|
|
{
|
|
if ( this == NULL )
|
|
return *this;
|
|
|
|
if (m_max_subsets < SetsSrc.m_max_subsets )
|
|
m_aSubSets = (CSubSet **) lcReAlloc(m_aSubSets, SetsSrc.m_max_subsets*sizeof(CSubSet*) );
|
|
|
|
m_cSets = SetsSrc.m_cSets;
|
|
m_max_subsets = SetsSrc.m_max_subsets;
|
|
if ( m_pszFilename )
|
|
lcFree( m_pszFilename );
|
|
m_pszFilename = lcStrDup( SetsSrc.m_pszFilename);
|
|
m_fPredefined = SetsSrc.m_fPredefined;
|
|
|
|
for(int i=0; i< m_cSets; i++)
|
|
{
|
|
if ( m_aSubSets[i] )
|
|
delete m_aSubSets[i];
|
|
|
|
*m_aSubSets[i] = *SetsSrc.m_aSubSets[i];
|
|
if ( SetsSrc.m_Toc == SetsSrc.m_aSubSets[i] )
|
|
m_Toc = m_aSubSets[i];
|
|
if ( SetsSrc.m_Index == SetsSrc.m_aSubSets[i] )
|
|
m_Index = m_aSubSets[i];
|
|
if ( SetsSrc.m_FTS == SetsSrc.m_aSubSets[i] )
|
|
m_FTS = m_aSubSets[i];
|
|
if ( SetsSrc.m_cur_Set == SetsSrc.m_aSubSets[i] )
|
|
m_cur_Set = m_aSubSets[i];
|
|
}
|
|
|
|
m_pIT = new CInfoType();
|
|
*m_pIT = *SetsSrc.m_pIT;
|
|
|
|
return *this;
|
|
}
|
|
|
|
#ifdef HHCTRL
|
|
|
|
void CSubSets::CopyTo( CHmData * const phmData )
|
|
{
|
|
CStr cszSubSetName;
|
|
CStr cszITName;
|
|
|
|
if ( !phmData->m_pdSubSets )
|
|
return;
|
|
for(int i=0; (phmData->m_pdSubSets[i].type>=SS_INCLUSIVE) && (phmData->m_pdSubSets[i].type<=SS_EXCLUSIVE); i++)
|
|
{
|
|
cszSubSetName = phmData->GetString( phmData->m_pdSubSets[i].dwStringSubSetName );
|
|
if ( GetSubSetIndex( cszSubSetName ) < 0 )
|
|
{
|
|
AddSubSet(); // create a new subset
|
|
m_cur_Set->m_cszSubSetName = cszSubSetName.psz;
|
|
m_cur_Set->m_bPredefined = TRUE;
|
|
}
|
|
cszITName = phmData->GetString( phmData->m_pdSubSets[i].dwStringITName );
|
|
int pos = m_pIT->m_itTables.m_ptblInfoTypes->IsStringInTable( cszITName.psz );
|
|
if ( pos <= 0 )
|
|
continue;
|
|
if ( phmData->m_pdSubSets[i].type == SS_INCLUSIVE )
|
|
m_cur_Set->AddIncType( pos ); // Add this "include" bit.
|
|
else
|
|
m_cur_Set->AddExcType( pos ); // Add this "exclude" bit.
|
|
}
|
|
|
|
// Read in all the user defined Subsets.
|
|
CState* pstate = phmData->m_pTitleCollection->GetState();
|
|
static const int MAX_PARAM = 4096;
|
|
CMem memParam( MAX_PARAM );
|
|
PSTR pszParam = (PSTR)memParam; // for notational convenience
|
|
DWORD cb;
|
|
int nKey=1;
|
|
char buf[5];
|
|
CStr cszKey = g_szUDSKey;
|
|
wsprintf(buf,"%d",nKey++);
|
|
cszKey += buf;
|
|
while( SUCCEEDED(pstate->Open(cszKey.psz,STGM_READ)) )
|
|
{
|
|
int type;
|
|
cszKey = g_szUDSKey;
|
|
wsprintf(buf, "%d", nKey++);
|
|
cszKey += buf;
|
|
if ( SUCCEEDED(pstate->Read(pszParam,MAX_PATH,&cb)) )
|
|
{
|
|
if ( isSameString( (PCSTR)pszParam, txtSSInclusive) )
|
|
type = SS_INCLUSIVE;
|
|
else
|
|
if ( isSameString((PCSTR)pszParam, txtSSExclusive) )
|
|
type = SS_EXCLUSIVE;
|
|
else
|
|
break;
|
|
}
|
|
else
|
|
break;
|
|
// format INCLUSIVE|EXCLUSIVE:SubSetName:ITName
|
|
PSTR psz = StrChr((PCSTR)pszParam, ':');
|
|
if (psz)
|
|
psz++;
|
|
else
|
|
psz = "";
|
|
CStr cszTemp = psz;
|
|
PSTR pszTemp = StrChr(cszTemp.psz, ':');
|
|
*pszTemp = '\0';
|
|
if ( GetSubSetIndex(cszTemp) < 0)
|
|
{
|
|
AddSubSet(); // create a new subset
|
|
m_cur_Set->m_cszSubSetName = cszTemp.psz;
|
|
m_cur_Set->m_bPredefined = FALSE; // The subset is user defined.
|
|
}
|
|
// Get the name of the type
|
|
psz = StrChr(psz, ':');
|
|
if ( psz )
|
|
psz++;
|
|
else
|
|
psz ="";
|
|
if (IsNonEmptyString(psz))
|
|
{
|
|
int pos = m_pIT->m_itTables.m_ptblInfoTypes->IsStringInTable( psz );
|
|
if ( pos <= 0 )
|
|
continue;
|
|
if ( type == SS_INCLUSIVE )
|
|
m_cur_Set->AddIncType( pos );
|
|
else if ( type == SS_EXCLUSIVE)
|
|
m_cur_Set->AddExcType( pos );
|
|
}
|
|
pstate->Close();
|
|
pstate->Delete();
|
|
} // while reading user defined subsets
|
|
|
|
for ( int n = 0; n < m_cSets; n++ )
|
|
m_aSubSets[n]->BuildMask();
|
|
}
|
|
#endif
|
|
|
|
// Import a subset
|
|
// ******************
|
|
CSubSet *CSubSets::AddSubSet(CSubSet *pSubSet )
|
|
{
|
|
if ( !pSubSet || pSubSet->m_cszSubSetName.IsEmpty() )
|
|
return NULL;
|
|
|
|
if ( GetSubSetIndex( pSubSet->m_cszSubSetName.psz ) >= 0)
|
|
return NULL; // the SS is already defined
|
|
|
|
if ( m_cSets >= m_max_subsets )
|
|
ReSizeSubSet(); // allocate space for more subsets
|
|
|
|
m_aSubSets[m_cSets] = new CSubSet( m_ITSize );
|
|
m_cur_Set = m_aSubSets[m_cSets];
|
|
m_cSets++;
|
|
|
|
*m_cur_Set = *pSubSet; // populate the new SubSet
|
|
|
|
return m_cur_Set;
|
|
}
|
|
|
|
|
|
|
|
// Create a new (empty) subset
|
|
// **********************
|
|
CSubSet *CSubSets::AddSubSet( )
|
|
{
|
|
|
|
if ( (m_cSets >= m_max_subsets) )
|
|
ReSizeSubSet();
|
|
|
|
m_aSubSets[m_cSets] = new CSubSet( m_ITSize);
|
|
m_cur_Set = m_aSubSets[m_cSets];
|
|
m_cSets++;
|
|
m_cur_Set->m_bPredefined = m_bPredefined; // from the base class
|
|
m_cur_Set->m_pIT = m_pIT;
|
|
|
|
return m_cur_Set;
|
|
}
|
|
|
|
|
|
|
|
// Removes a subset from m_aSubSets.
|
|
// ***********************************
|
|
void CSubSets::RemoveSubSet( PCSTR pszName )
|
|
{
|
|
int pos;
|
|
|
|
if ( IsEmptyString(pszName) )
|
|
return;
|
|
pos = GetSubSetIndex( pszName );
|
|
if ( (pos < 0) || (pos>m_max_subsets) )
|
|
return; // subset name is not defined
|
|
delete m_aSubSets[pos];
|
|
m_aSubSets[pos] = NULL;
|
|
m_cur_Set = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NOTE:
|
|
// Only user defined Subsets are saved to file. Author defined subsets (ie predefined
|
|
// subsets live in the master .chm file. And are saved in the .hhp file and in the future
|
|
// in the .hhc and .hhk file.
|
|
|
|
// First try to save in the same directory as the .chm is in. next put it in the windows help directory.
|
|
//
|
|
// Format:
|
|
// [SUBSETS]
|
|
// SetName:Inclusive:TypeName
|
|
// SetName:Exclusive:TypeName
|
|
BOOL CSubSets::SaveToFile( PCSTR filename )
|
|
{
|
|
|
|
if ( m_fPredefined )
|
|
return FALSE;
|
|
// finish this
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL CSubSets::ReadFromFile( PCSTR filename )
|
|
{
|
|
|
|
// finish this
|
|
|
|
|
|
if ( m_fPredefined )
|
|
return FALSE;
|
|
// Read the user defined subsets from the .sub file and add them to this subset.
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CSubSets::GetSubSetIndex( PCSTR pszName ) const
|
|
{
|
|
for (int i=0; i<m_cSets; i++ )
|
|
{
|
|
if (m_aSubSets[i] && m_aSubSets[i]->IsSameSet( pszName ) )
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
// Adds 5 more subsets.
|
|
void CSubSets::ReSizeSubSet()
|
|
{
|
|
ASSERT(m_aSubSets);
|
|
|
|
m_max_subsets += 5;
|
|
|
|
m_aSubSets = (CSubSet**)lcReAlloc( m_aSubSets, m_max_subsets * sizeof(CSubSet*) );
|
|
|
|
}
|
|
|
|
#ifdef HHCTRL
|
|
|
|
void CSubSets::SetTocMask( PCSTR psz, CHHWinType* phh)
|
|
{
|
|
CSubSet* pSS;
|
|
|
|
int i = GetSubSetIndex(psz);
|
|
if ( i >= 0 )
|
|
pSS = m_aSubSets[i];
|
|
else
|
|
pSS = NULL;
|
|
|
|
if ( pSS != m_Toc )
|
|
{
|
|
m_Toc = pSS;
|
|
// Need to re-init the TOC!
|
|
if (phh)
|
|
phh->UpdateInformationTypes();
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CSubSet
|
|
//
|
|
|
|
CSubSet::CSubSet(int const ITSize)
|
|
{
|
|
// Round up to nearest DWORD boundary and allocate the bit fields. We have to do this becuase
|
|
// m_pInclusive and m_pExclusive are DWORD pointers rather than byte pointers. As an optimization, if
|
|
// ITSize is <= 4 We'll just use CSubSet member DWORDS as the bit fields. <mc>
|
|
//
|
|
int iRem = ITSize % 4;
|
|
if ( iRem )
|
|
m_ITSize = (ITSize + (4 - iRem));
|
|
else
|
|
m_ITSize = ITSize;
|
|
|
|
if ( ITSize > 4 )
|
|
{
|
|
m_pInclusive = (INFOTYPE*) lcCalloc(m_ITSize);
|
|
m_pExclusive = (INFOTYPE*) lcCalloc(m_ITSize);
|
|
}
|
|
else
|
|
{
|
|
dwI = dwE = 0;
|
|
m_pInclusive = &dwI;
|
|
m_pExclusive = &dwE;
|
|
}
|
|
m_aCatMasks = NULL;
|
|
m_bIsEntireCollection = FALSE;
|
|
}
|
|
|
|
CSubSet::~CSubSet()
|
|
{
|
|
if ( m_ITSize > 4 )
|
|
{
|
|
if ( m_pInclusive )
|
|
lcFree(m_pInclusive);
|
|
if ( m_pExclusive )
|
|
lcFree(m_pExclusive);
|
|
}
|
|
if ( m_aCatMasks )
|
|
{
|
|
for(int i=0; i<m_pIT->HowManyCategories(); i++)
|
|
lcFree(m_aCatMasks[i]);
|
|
lcFree(m_aCatMasks);
|
|
}
|
|
}
|
|
|
|
|
|
// Copy constructor
|
|
// *********************
|
|
const CSubSet& CSubSet::operator=(const CSubSet& SetSrc)
|
|
{
|
|
if ( this == NULL )
|
|
return *this;
|
|
if ( this == &SetSrc )
|
|
return *this;
|
|
m_cszSubSetName = SetSrc.m_cszSubSetName.psz; // copy the set name
|
|
memcpy(m_pInclusive, SetSrc.m_pInclusive, SetSrc.m_ITSize);
|
|
memcpy(m_pExclusive, SetSrc.m_pExclusive, SetSrc.m_ITSize);
|
|
m_ITSize = SetSrc.m_ITSize;
|
|
m_bPredefined = SetSrc.m_bPredefined;
|
|
m_pIT = SetSrc.m_pIT;
|
|
return *this;
|
|
}
|
|
|
|
|
|
void CSubSet::BuildMask(void)
|
|
{
|
|
if ( m_bIsEntireCollection )
|
|
return;
|
|
|
|
int cCategories = m_pIT->HowManyCategories();
|
|
m_aCatMasks = (INFOTYPE **) lcCalloc(cCategories * sizeof(INFOTYPE *) );
|
|
for(int i =0; i<cCategories; i++)
|
|
{
|
|
INFOTYPE *pIT, *pCatMask;
|
|
m_aCatMasks[i] = (INFOTYPE*)lcCalloc( m_ITSize);
|
|
pIT = m_aCatMasks[i];
|
|
INFOTYPE *pSSMask = m_pInclusive;
|
|
pCatMask = m_pIT->m_itTables.m_aCategories[i].pInfoType;
|
|
for(int j=0; j<m_ITSize; j+=4)
|
|
{
|
|
*pIT = (*pSSMask & *pCatMask);
|
|
pIT++;
|
|
pCatMask++;
|
|
pSSMask++;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CSubSet::IsSameSet (PCSTR pszName) const
|
|
{
|
|
if ( pszName && strcmp(m_cszSubSetName.psz, pszName) == 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static int ExclusiveOffset=-1;
|
|
static INFOTYPE curExclusiveBit=1;
|
|
|
|
int CSubSet::GetFirstExcITinSubSet(void) const
|
|
{
|
|
ExclusiveOffset = -1;
|
|
curExclusiveBit = 1;
|
|
|
|
int pos = GetITBitfromIT(m_pExclusive,
|
|
&ExclusiveOffset,
|
|
&curExclusiveBit,
|
|
m_ITSize*8 );
|
|
while ( (pos != -1) && IsDeleted(pos) )
|
|
pos = GetNextExcITinSubSet();
|
|
return pos;
|
|
}
|
|
|
|
|
|
|
|
int CSubSet::GetNextExcITinSubSet(void) const
|
|
{
|
|
if ( ExclusiveOffset <=-1 || curExclusiveBit <=1 )
|
|
return -1;
|
|
|
|
return GetITBitfromIT(m_pExclusive,
|
|
&ExclusiveOffset,
|
|
&curExclusiveBit,
|
|
m_ITSize*8 );
|
|
}
|
|
|
|
|
|
|
|
static int InclusiveOffset=-1;
|
|
static INFOTYPE curInclusiveBit=1;
|
|
|
|
int CSubSet::GetFirstIncITinSubSet( void) const
|
|
{
|
|
|
|
InclusiveOffset = -1;
|
|
curInclusiveBit = 1;
|
|
|
|
int pos = GetITBitfromIT(m_pInclusive,
|
|
&InclusiveOffset,
|
|
&curInclusiveBit,
|
|
m_ITSize*8 );
|
|
while ( (pos != -1) && IsDeleted( pos ) )
|
|
pos = GetNextIncITinSubSet();
|
|
return pos;
|
|
}
|
|
|
|
|
|
int CSubSet::GetNextIncITinSubSet( void) const
|
|
{
|
|
|
|
if ( InclusiveOffset <= -1 || curInclusiveBit <= 1 )
|
|
return -1;
|
|
|
|
return GetITBitfromIT(m_pInclusive,
|
|
&InclusiveOffset,
|
|
&curInclusiveBit,
|
|
m_ITSize*8 );
|
|
}
|
|
|
|
|
|
BOOL CSubSet::Filter( INFOTYPE const *pTopicIT ) const
|
|
{
|
|
INFOTYPE const *pTopicOffset = pTopicIT;
|
|
INFOTYPE MaskOffset;
|
|
//INFOTYPE *pExcITOffset, ExcITMask, ExcITBits;
|
|
int cCategories = m_pIT->HowManyCategories();
|
|
BOOL NoMask;
|
|
|
|
if ( m_bIsEntireCollection )
|
|
return TRUE;
|
|
|
|
// Filter on the Subset's Exclusive Bit Mask
|
|
#if 0
|
|
pTopicOffset = pTopicIT;
|
|
memcpy(&MaskOffset,m_pInclusive, sizeof(INFOTYPE) );
|
|
memcpy(&ExcITBits, m_pExclusive, sizeof(INFOTYPE) );
|
|
pExcITOffset = m_pIT->m_itTables.m_pExclusive;
|
|
ExcITMask = MaskOffset & *pExcITOffset; // ExcITMask has the EX ITs that are set in the filter.
|
|
ExcITMask = (~ExcITMask | ExcITBits); // flip the exclusive bits in the filter mask
|
|
ExcITMask = ExcITMask ^ ~*pExcITOffset; // To get rid of those extra 1's from the previous ~.
|
|
#endif
|
|
NoMask = FALSE;
|
|
for ( int i=0; i<m_ITSize; i+=4)
|
|
{
|
|
#if 0
|
|
if ( (ExcITMask & *pTopicOffset) )
|
|
return FALSE;
|
|
memcpy(&MaskOffset,m_pInclusive+i, sizeof(INFOTYPE) );
|
|
memcpy(&ExcITBits, m_pExclusive+i, sizeof(INFOTYPE) );
|
|
pTopicOffset++;
|
|
pExcITOffset++;
|
|
ExcITMask = MaskOffset & *pExcITOffset; // ExcITMask has the EX ITs that are set in the filter.
|
|
ExcITMask = (~ExcITMask | ExcITBits); // flip the exclusive bits in the filter mask
|
|
ExcITMask = ExcITMask ^ ~*pExcITOffset; // To get rid of those extra 1's from the previous ~.
|
|
#else
|
|
if ( *m_pExclusive & *pTopicOffset )
|
|
return FALSE;
|
|
#endif
|
|
}
|
|
|
|
// Filter on the Subset's Inclusive Bit Mask
|
|
#if 0
|
|
if ( cCategories > 0)
|
|
{
|
|
for (int i=0; i<cCategories; i++)
|
|
{
|
|
pTopicOffset = pTopicIT;
|
|
pMaskOffset = m_aCatMasks[i];
|
|
#if 0
|
|
NoMask = TRUE;
|
|
for( int j=0; j<m_ITSize; j+=4)
|
|
{
|
|
if ( NoMask && *pTopicOffset == 0L )
|
|
NoMask = TRUE;
|
|
else
|
|
NoMask = FALSE;
|
|
|
|
if (! *pMaskOffset )
|
|
{
|
|
pMaskOffset++;
|
|
pTopicOffset++;
|
|
continue;
|
|
}
|
|
|
|
if (!NoMask && !(*pMaskOffset & *pTopicOffset) )
|
|
return FALSE;
|
|
pMaskOffset++;
|
|
pTopicOffset++;
|
|
}
|
|
#endif
|
|
BOOL bOk = TRUE;
|
|
for(int j=0; j<m_ITSize; j+=4, pMaskOffset++, pTopicOffset++ )
|
|
{
|
|
if ( *pTopicOffset == 0L || *pMaskOffset == 0L )
|
|
continue;
|
|
if ( (bOk = (BOOL)(*pMaskOffset & *pTopicOffset)) )
|
|
break;
|
|
}
|
|
if (! bOk )
|
|
{
|
|
//
|
|
// Before we filter the topic out of existance we need to figure out if the topic is void of
|
|
// any IT's from the current catagory. If it is we will NOT filter this topic based upon subset
|
|
// bits for this catagory.
|
|
//
|
|
for(int n=0; n < (m_ITSize / 4); n++)
|
|
{
|
|
if ( m_pIT->m_itTables.m_aCategories[i].pInfoType[n] & pTopicIT[n] )
|
|
return FALSE; // Yep, topic has an IT from the catagory.
|
|
}
|
|
}
|
|
if (NoMask && *pTopicIT&1L ) // bit zero ==1 Inclusive logic
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{ // No categories,
|
|
pTopicOffset = pTopicIT;
|
|
MaskOffset = *m_pInclusive;
|
|
BOOL NoMask = TRUE;
|
|
for ( int i=0; i<m_ITSize/4; i++)
|
|
{
|
|
if ( NoMask && *pTopicOffset == 0L )
|
|
NoMask = TRUE;
|
|
else
|
|
NoMask = FALSE;
|
|
// MaskOffset &= ~(*(m_pIT->m_itTables.m_pExclusive+i));
|
|
if (!NoMask && !(MaskOffset & *pTopicOffset) )
|
|
return FALSE;
|
|
MaskOffset = (*m_pInclusive)+i;
|
|
pTopicOffset++;
|
|
}
|
|
if (NoMask && *pTopicIT&1L ) // bit zero ==1 Inclusive logic
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|