383 lines
10 KiB
C++
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.
|
|
}
|