windows-nt/Source/XPSP1/NT/enduser/stuff/hhctrl/genit.cpp
2020-09-26 16:20:57 +08:00

383 lines
10 KiB
C++

#include "header.h"
#include "sitemap.h"
// Static Data
// ******************
static INFOTYPE curr_bit; // used for getting the next IT in a category
static int curr_cat;
static int curr_offset; // There are 32 info type bits per offset.
// ********************************************************
//
// Methods to operate on CSitemap Categories of Information Types
//
// ********************************************************
void CSiteMap::AddITtoCategory(int cat, int type)
{
int offset;
INFOTYPE *pInfoType;
if ( cat < 0 )
return;
m_itTables.m_aCategories[cat].c_Types++;
offset = type / 32;
pInfoType = m_itTables.m_aCategories[cat].pInfoType + offset;
*pInfoType |= 1<<type;
if ( m_itTables.m_max_categories == (cat+1) )
{
m_itTables.m_aCategories = (CATEGORY_TYPE*) lcReAlloc( m_itTables.m_aCategories, (m_itTables.m_max_categories+5) * sizeof(CATEGORY_TYPE) );
for(int i=m_itTables.m_max_categories; i < m_itTables.m_max_categories+5; i++)
m_itTables.m_aCategories[i].pInfoType = (INFOTYPE*)lcCalloc(InfoTypeSize());
m_itTables.m_max_categories += 5;
}
}
void CSiteMap::DeleteITfromCat(int cat, int type)
{
int offset;
INFOTYPE *pInfoType;
if ( cat < 0 )
return;
m_itTables.m_aCategories[cat].c_Types--;
offset = type / 32;
pInfoType = m_itTables.m_aCategories[cat].pInfoType + offset;
*pInfoType &= ~(1<<type);
}
int CSiteMap::GetFirstCategoryType( int pos ) const
{
curr_offset = -1; // gets incermented to 0 before first IT comparison.
curr_cat = pos; // keep the position of the category for calls to GetNextITinCagetory.
curr_bit =1; // bit zero of offset zero is reserved. But check it any way.
if ( pos < 0 )
return -1;
int bitpos = GetITfromCat(&curr_offset,
&curr_bit,
m_itTables.m_aCategories[curr_cat].pInfoType,
InfoTypeSize()*8);
if( (bitpos!=-1) && (IsDeleted(bitpos)) )
bitpos = GetNextITinCategory();
return bitpos;
}
int CSiteMap::GetNextITinCategory( void ) const
{
if ( curr_cat < 0 )
return -1; // must call GetFirstCategoryType() before calling this fn.
int pos = GetITfromCat(&curr_offset,
&curr_bit,
m_itTables.m_aCategories[curr_cat].pInfoType,
InfoTypeSize()*8);
while ( (pos!=-1) && (IsDeleted(pos)))
pos = GetITfromCat(&curr_offset,
&curr_bit,
m_itTables.m_aCategories[curr_cat].pInfoType,
InfoTypeSize()*8);
return pos;
}
int CSiteMap::GetLastCategoryType(int pos) const
{ int cat;
int offset;
INFOTYPE bit;
cat = pos; // The category
if ( cat < 0 )
return -1;
offset = -1;
bit = 1;
for (int i=0; i<m_itTables.m_aCategories[cat].c_Types-1; i++)
if ( GetITfromCat(&offset,
&bit,
m_itTables.m_aCategories[cat].pInfoType,
InfoTypeSize()*8 ) == -1 )
return -1;
return GetITfromCat(&offset,
&bit,
m_itTables.m_aCategories[cat].pInfoType,
InfoTypeSize() * 8 );
}
static int BitToDec( int binary )
{
register int count=0;
register int bit=1;
// if ( binary < 1 )
// return -1;
if ( binary == 1 )
return 1;
while ( bit != binary )
{
bit = bit<<1;
count++;
}
return count;
}
// ***********************************************
//
// Generic methods to operate on Categories.
//
// ***********************************************
/*
GetITfromCat A helper function used to convert a bit position to it's to a decimal number.
Given a Category and offset, and a bit field with on bit set returns the
next bit set in the category. ie. a bit corresponds to an information
type.
Parameters:
int const cat <I> The category to work on
int* offset <I/O> The offset into the infotype bits, an offset is 4 bytes long
must be -1 for the first offset, 0 for second offset ...
int* bit <I/O> The first bit position to test.
Return Value The decimal number of the bit position. ie. bit position 5 returns 5.
*/
int GetITfromCat(int* offset, INFOTYPE* bit, INFOTYPE* pInfoType, int cTypes)
{
INFOTYPE InfoType;
if ( *offset < 0 )
*offset = 0;
memcpy(&InfoType, pInfoType + *offset, sizeof(INFOTYPE) );
for(int i=BitToDec(*bit)+(*offset*32); i < cTypes; i++)
{ // offset: 0 1 2
if ( i % 32 == 0 )// 0-31, 32-63, 64-95 ...
{
(*offset)++;
*bit = 1; // bit 0, 32, 64 ... depending on the offset.
memcpy(&InfoType, pInfoType + *offset, sizeof(INFOTYPE) );
}
if ( *bit & InfoType )
{
int ret = (int)((*offset*32)+(BitToDec(*bit))); // return the decimal value of the bit position.
*bit = *bit << 1;
return ret;
}
else
*bit = *bit << 1;
}
return -1; // There are no infotypes in this category.
}
// ******************************************************
//
// Methods to operate on CSiteMap Exclusive Information Types
//
// ******************************************************
static int ExclusiveOffset = -1; // Gets incermented to zero before search begins
static INFOTYPE ExclusiveBit = 1; // check bit 0 even though it is reserved.
int CSiteMap::GetFirstExclusive(int offset, INFOTYPE bit) const
{
ExclusiveOffset = offset;
ExclusiveBit = bit;
int pos = GetITBitfromIT(m_itTables.m_pExclusive,
&ExclusiveOffset,
&ExclusiveBit,
InfoTypeSize()*8 );
if( (pos!=-1) && (IsDeleted(pos)) )
pos = GetNextExclusive();
return pos;
}
int CSiteMap::GetNextExclusive(void) const
{
if ( ExclusiveOffset < -1 || ExclusiveBit < 1 )
return -1;
int pos = GetITBitfromIT(m_itTables.m_pExclusive,
&ExclusiveOffset,
&ExclusiveBit,
InfoTypeSize()*8 );
while ((pos!=-1) && (IsDeleted(pos)))
pos = GetITBitfromIT(m_itTables.m_pExclusive,
&ExclusiveOffset,
&ExclusiveBit,
InfoTypeSize()*8 );
return pos;
}
int CSiteMap::GetLastExclusive(void) const
{
int i;
int iLastExclusive=-1, temp;
int offset=-1;
INFOTYPE bit=1;
for (i=0; i< HowManyInfoTypes(); i++)
if ( (temp = GetITBitfromIT(m_itTables.m_pExclusive, &offset, &bit, InfoTypeSize()*8)) == -1 )
return iLastExclusive;
else
iLastExclusive = temp;
return -1;
}
// ******************************************************
//
// Methods to operate on CSiteMap Hidden Information Types
//
// ******************************************************
static int HiddenOffset=-1;
static INFOTYPE HiddenBit=1;
int CSiteMap::GetFirstHidden(int offset, INFOTYPE bit) const
{
HiddenOffset = offset;
HiddenBit = bit;
int pos = GetITBitfromIT(m_itTables.m_pHidden,
&HiddenOffset,
&HiddenBit,
InfoTypeSize()*8 );
if( (pos != -1) && (IsDeleted(pos)) )
pos = GetNextHidden();
return pos;
}
int CSiteMap::GetNextHidden(void) const
{
if ( HiddenOffset < -1 || HiddenBit < 1 )
return -1;
int pos = GetITBitfromIT(m_itTables.m_pHidden,
&HiddenOffset,
&HiddenBit,
InfoTypeSize()*8 );
while((pos!=-1) &&(IsDeleted(pos)) )
pos = GetITBitfromIT(m_itTables.m_pHidden,
&HiddenOffset,
&HiddenBit,
InfoTypeSize()*8 );
return pos;
}
int CSiteMap::GetLastHidden(void) const
{
int i;
int iLastHidden=-1, temp;
int offset=-1;
INFOTYPE bit=1;
for (i=0; i<HowManyInfoTypes(); i++)
if ( (temp = GetITBitfromIT(m_itTables.m_pHidden, &offset, &bit, InfoTypeSize()*8)) == -1)
return iLastHidden;
else
iLastHidden = temp;
return -1;
}
// ***************************************************************************
//
// Generic Methods to operate on Hidden and Exclusive Information Types
//
// ***************************************************************************
void DeleteIT(int const type, INFOTYPE *pIT )
{
int offset;
INFOTYPE *pInfoType;
INFOTYPE deleteIT;
if ( type <= 0 || !pIT)
return;
deleteIT = 1<<type;
offset = type / 32;
pInfoType = pIT + offset;
*pInfoType &= ~deleteIT;
}
void AddIT(int const type, INFOTYPE *pIT )
{
int offset;
INFOTYPE *pInfoType;
if ( type <= 0 || !pIT)
return;
offset = type / 32;
pInfoType = pIT + offset;
*pInfoType |= 1<<type;
}
void CopyITBits(INFOTYPE** ITDst, INFOTYPE* ITSrc, int size)
{
if ( !*ITDst || !ITSrc )
return;
lcFree( *ITDst );
*ITDst = (INFOTYPE*)lcCalloc( size );
memcpy( *ITDst, ITSrc, size);
}
int GetITBitfromIT(INFOTYPE const *IT, int* offset, INFOTYPE* bit, int cTypes)
{
INFOTYPE InfoType;
if ( *offset < 0 )
*offset = 0;
memcpy(&InfoType, IT + *offset, sizeof(INFOTYPE) );
for(int i=BitToDec(*bit)+(*offset*32); i < cTypes; i++) // we are checking bit 0 even though it is reserved.
{ // offset: 0 1 2
if ( i % 32 == 0 )// 0-31, 32-63, 64-95 ...
{
(*offset)++;
*bit = 1; // bit 0, 32, 64 ... depending on the offset.
memcpy(&InfoType, IT + *offset, sizeof(INFOTYPE) );
}
if ( *bit & InfoType )
{
int ret = (int)((*offset*32)+(BitToDec(*bit))); // return the decimal value of the bit position.
*bit = *bit << 1;
return ret;
}
else
*bit = *bit << 1;
}
return -1; // There are no infotype bits in this InfoType field.
}