#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. }