Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
10 KiB

  1. #include "header.h"
  2. #include "sitemap.h"
  3. // Static Data
  4. // ******************
  5. static INFOTYPE curr_bit; // used for getting the next IT in a category
  6. static int curr_cat;
  7. static int curr_offset; // There are 32 info type bits per offset.
  8. // ********************************************************
  9. //
  10. // Methods to operate on CSitemap Categories of Information Types
  11. //
  12. // ********************************************************
  13. void CSiteMap::AddITtoCategory(int cat, int type)
  14. {
  15. int offset;
  16. INFOTYPE *pInfoType;
  17. if ( cat < 0 )
  18. return;
  19. m_itTables.m_aCategories[cat].c_Types++;
  20. offset = type / 32;
  21. pInfoType = m_itTables.m_aCategories[cat].pInfoType + offset;
  22. *pInfoType |= 1<<type;
  23. if ( m_itTables.m_max_categories == (cat+1) )
  24. {
  25. m_itTables.m_aCategories = (CATEGORY_TYPE*) lcReAlloc( m_itTables.m_aCategories, (m_itTables.m_max_categories+5) * sizeof(CATEGORY_TYPE) );
  26. for(int i=m_itTables.m_max_categories; i < m_itTables.m_max_categories+5; i++)
  27. m_itTables.m_aCategories[i].pInfoType = (INFOTYPE*)lcCalloc(InfoTypeSize());
  28. m_itTables.m_max_categories += 5;
  29. }
  30. }
  31. void CSiteMap::DeleteITfromCat(int cat, int type)
  32. {
  33. int offset;
  34. INFOTYPE *pInfoType;
  35. if ( cat < 0 )
  36. return;
  37. m_itTables.m_aCategories[cat].c_Types--;
  38. offset = type / 32;
  39. pInfoType = m_itTables.m_aCategories[cat].pInfoType + offset;
  40. *pInfoType &= ~(1<<type);
  41. }
  42. int CSiteMap::GetFirstCategoryType( int pos ) const
  43. {
  44. curr_offset = -1; // gets incermented to 0 before first IT comparison.
  45. curr_cat = pos; // keep the position of the category for calls to GetNextITinCagetory.
  46. curr_bit =1; // bit zero of offset zero is reserved. But check it any way.
  47. if ( pos < 0 )
  48. return -1;
  49. int bitpos = GetITfromCat(&curr_offset,
  50. &curr_bit,
  51. m_itTables.m_aCategories[curr_cat].pInfoType,
  52. InfoTypeSize()*8);
  53. if( (bitpos!=-1) && (IsDeleted(bitpos)) )
  54. bitpos = GetNextITinCategory();
  55. return bitpos;
  56. }
  57. int CSiteMap::GetNextITinCategory( void ) const
  58. {
  59. if ( curr_cat < 0 )
  60. return -1; // must call GetFirstCategoryType() before calling this fn.
  61. int pos = GetITfromCat(&curr_offset,
  62. &curr_bit,
  63. m_itTables.m_aCategories[curr_cat].pInfoType,
  64. InfoTypeSize()*8);
  65. while ( (pos!=-1) && (IsDeleted(pos)))
  66. pos = GetITfromCat(&curr_offset,
  67. &curr_bit,
  68. m_itTables.m_aCategories[curr_cat].pInfoType,
  69. InfoTypeSize()*8);
  70. return pos;
  71. }
  72. int CSiteMap::GetLastCategoryType(int pos) const
  73. { int cat;
  74. int offset;
  75. INFOTYPE bit;
  76. cat = pos; // The category
  77. if ( cat < 0 )
  78. return -1;
  79. offset = -1;
  80. bit = 1;
  81. for (int i=0; i<m_itTables.m_aCategories[cat].c_Types-1; i++)
  82. if ( GetITfromCat(&offset,
  83. &bit,
  84. m_itTables.m_aCategories[cat].pInfoType,
  85. InfoTypeSize()*8 ) == -1 )
  86. return -1;
  87. return GetITfromCat(&offset,
  88. &bit,
  89. m_itTables.m_aCategories[cat].pInfoType,
  90. InfoTypeSize() * 8 );
  91. }
  92. static int BitToDec( int binary )
  93. {
  94. register int count=0;
  95. register int bit=1;
  96. // if ( binary < 1 )
  97. // return -1;
  98. if ( binary == 1 )
  99. return 1;
  100. while ( bit != binary )
  101. {
  102. bit = bit<<1;
  103. count++;
  104. }
  105. return count;
  106. }
  107. // ***********************************************
  108. //
  109. // Generic methods to operate on Categories.
  110. //
  111. // ***********************************************
  112. /*
  113. GetITfromCat A helper function used to convert a bit position to it's to a decimal number.
  114. Given a Category and offset, and a bit field with on bit set returns the
  115. next bit set in the category. ie. a bit corresponds to an information
  116. type.
  117. Parameters:
  118. int const cat <I> The category to work on
  119. int* offset <I/O> The offset into the infotype bits, an offset is 4 bytes long
  120. must be -1 for the first offset, 0 for second offset ...
  121. int* bit <I/O> The first bit position to test.
  122. Return Value The decimal number of the bit position. ie. bit position 5 returns 5.
  123. */
  124. int GetITfromCat(int* offset, INFOTYPE* bit, INFOTYPE* pInfoType, int cTypes)
  125. {
  126. INFOTYPE InfoType;
  127. if ( *offset < 0 )
  128. *offset = 0;
  129. memcpy(&InfoType, pInfoType + *offset, sizeof(INFOTYPE) );
  130. for(int i=BitToDec(*bit)+(*offset*32); i < cTypes; i++)
  131. { // offset: 0 1 2
  132. if ( i % 32 == 0 )// 0-31, 32-63, 64-95 ...
  133. {
  134. (*offset)++;
  135. *bit = 1; // bit 0, 32, 64 ... depending on the offset.
  136. memcpy(&InfoType, pInfoType + *offset, sizeof(INFOTYPE) );
  137. }
  138. if ( *bit & InfoType )
  139. {
  140. int ret = (int)((*offset*32)+(BitToDec(*bit))); // return the decimal value of the bit position.
  141. *bit = *bit << 1;
  142. return ret;
  143. }
  144. else
  145. *bit = *bit << 1;
  146. }
  147. return -1; // There are no infotypes in this category.
  148. }
  149. // ******************************************************
  150. //
  151. // Methods to operate on CSiteMap Exclusive Information Types
  152. //
  153. // ******************************************************
  154. static int ExclusiveOffset = -1; // Gets incermented to zero before search begins
  155. static INFOTYPE ExclusiveBit = 1; // check bit 0 even though it is reserved.
  156. int CSiteMap::GetFirstExclusive(int offset, INFOTYPE bit) const
  157. {
  158. ExclusiveOffset = offset;
  159. ExclusiveBit = bit;
  160. int pos = GetITBitfromIT(m_itTables.m_pExclusive,
  161. &ExclusiveOffset,
  162. &ExclusiveBit,
  163. InfoTypeSize()*8 );
  164. if( (pos!=-1) && (IsDeleted(pos)) )
  165. pos = GetNextExclusive();
  166. return pos;
  167. }
  168. int CSiteMap::GetNextExclusive(void) const
  169. {
  170. if ( ExclusiveOffset < -1 || ExclusiveBit < 1 )
  171. return -1;
  172. int pos = GetITBitfromIT(m_itTables.m_pExclusive,
  173. &ExclusiveOffset,
  174. &ExclusiveBit,
  175. InfoTypeSize()*8 );
  176. while ((pos!=-1) && (IsDeleted(pos)))
  177. pos = GetITBitfromIT(m_itTables.m_pExclusive,
  178. &ExclusiveOffset,
  179. &ExclusiveBit,
  180. InfoTypeSize()*8 );
  181. return pos;
  182. }
  183. int CSiteMap::GetLastExclusive(void) const
  184. {
  185. int i;
  186. int iLastExclusive=-1, temp;
  187. int offset=-1;
  188. INFOTYPE bit=1;
  189. for (i=0; i< HowManyInfoTypes(); i++)
  190. if ( (temp = GetITBitfromIT(m_itTables.m_pExclusive, &offset, &bit, InfoTypeSize()*8)) == -1 )
  191. return iLastExclusive;
  192. else
  193. iLastExclusive = temp;
  194. return -1;
  195. }
  196. // ******************************************************
  197. //
  198. // Methods to operate on CSiteMap Hidden Information Types
  199. //
  200. // ******************************************************
  201. static int HiddenOffset=-1;
  202. static INFOTYPE HiddenBit=1;
  203. int CSiteMap::GetFirstHidden(int offset, INFOTYPE bit) const
  204. {
  205. HiddenOffset = offset;
  206. HiddenBit = bit;
  207. int pos = GetITBitfromIT(m_itTables.m_pHidden,
  208. &HiddenOffset,
  209. &HiddenBit,
  210. InfoTypeSize()*8 );
  211. if( (pos != -1) && (IsDeleted(pos)) )
  212. pos = GetNextHidden();
  213. return pos;
  214. }
  215. int CSiteMap::GetNextHidden(void) const
  216. {
  217. if ( HiddenOffset < -1 || HiddenBit < 1 )
  218. return -1;
  219. int pos = GetITBitfromIT(m_itTables.m_pHidden,
  220. &HiddenOffset,
  221. &HiddenBit,
  222. InfoTypeSize()*8 );
  223. while((pos!=-1) &&(IsDeleted(pos)) )
  224. pos = GetITBitfromIT(m_itTables.m_pHidden,
  225. &HiddenOffset,
  226. &HiddenBit,
  227. InfoTypeSize()*8 );
  228. return pos;
  229. }
  230. int CSiteMap::GetLastHidden(void) const
  231. {
  232. int i;
  233. int iLastHidden=-1, temp;
  234. int offset=-1;
  235. INFOTYPE bit=1;
  236. for (i=0; i<HowManyInfoTypes(); i++)
  237. if ( (temp = GetITBitfromIT(m_itTables.m_pHidden, &offset, &bit, InfoTypeSize()*8)) == -1)
  238. return iLastHidden;
  239. else
  240. iLastHidden = temp;
  241. return -1;
  242. }
  243. // ***************************************************************************
  244. //
  245. // Generic Methods to operate on Hidden and Exclusive Information Types
  246. //
  247. // ***************************************************************************
  248. void DeleteIT(int const type, INFOTYPE *pIT )
  249. {
  250. int offset;
  251. INFOTYPE *pInfoType;
  252. INFOTYPE deleteIT;
  253. if ( type <= 0 || !pIT)
  254. return;
  255. deleteIT = 1<<type;
  256. offset = type / 32;
  257. pInfoType = pIT + offset;
  258. *pInfoType &= ~deleteIT;
  259. }
  260. void AddIT(int const type, INFOTYPE *pIT )
  261. {
  262. int offset;
  263. INFOTYPE *pInfoType;
  264. if ( type <= 0 || !pIT)
  265. return;
  266. offset = type / 32;
  267. pInfoType = pIT + offset;
  268. *pInfoType |= 1<<type;
  269. }
  270. void CopyITBits(INFOTYPE** ITDst, INFOTYPE* ITSrc, int size)
  271. {
  272. if ( !*ITDst || !ITSrc )
  273. return;
  274. lcFree( *ITDst );
  275. *ITDst = (INFOTYPE*)lcCalloc( size );
  276. memcpy( *ITDst, ITSrc, size);
  277. }
  278. int GetITBitfromIT(INFOTYPE const *IT, int* offset, INFOTYPE* bit, int cTypes)
  279. {
  280. INFOTYPE InfoType;
  281. if ( *offset < 0 )
  282. *offset = 0;
  283. memcpy(&InfoType, IT + *offset, sizeof(INFOTYPE) );
  284. for(int i=BitToDec(*bit)+(*offset*32); i < cTypes; i++) // we are checking bit 0 even though it is reserved.
  285. { // offset: 0 1 2
  286. if ( i % 32 == 0 )// 0-31, 32-63, 64-95 ...
  287. {
  288. (*offset)++;
  289. *bit = 1; // bit 0, 32, 64 ... depending on the offset.
  290. memcpy(&InfoType, IT + *offset, sizeof(INFOTYPE) );
  291. }
  292. if ( *bit & InfoType )
  293. {
  294. int ret = (int)((*offset*32)+(BitToDec(*bit))); // return the decimal value of the bit position.
  295. *bit = *bit << 1;
  296. return ret;
  297. }
  298. else
  299. *bit = *bit << 1;
  300. }
  301. return -1; // There are no infotype bits in this InfoType field.
  302. }