Leaked source code of windows server 2003
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.

422 lines
9.4 KiB

  1. /*++
  2. Copyright (C) 1999- Microsoft Corporation
  3. Module Name:
  4. typeutil.h
  5. Abstract:
  6. This module declares useful types such as CWiaArray and CWiaMap.
  7. These were lifted from the ATL library (atlbase.h).
  8. Author:
  9. DavePar
  10. Revision History:
  11. --*/
  12. #ifndef TYPEUTIL__H_
  13. #define TYPEUTIL__H_
  14. #ifndef ASSERT
  15. #define ASSERT(x)
  16. #endif
  17. /////////////////////////////////////////////////////////////////////////////
  18. // Collection helpers - CWiaArray & CWiaMap
  19. template <class T>
  20. class CWiaArray
  21. {
  22. public:
  23. T* m_aT;
  24. int m_nSize;
  25. int m_nAllocSize;
  26. // Construction/destruction
  27. CWiaArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
  28. { }
  29. ~CWiaArray()
  30. {
  31. RemoveAll();
  32. }
  33. // Operations
  34. int GetSize() const
  35. {
  36. return m_nSize;
  37. }
  38. BOOL GrowTo(int size)
  39. {
  40. if (size > m_nAllocSize)
  41. {
  42. T* aT;
  43. aT = (T*) realloc(m_aT, size * sizeof(T));
  44. if (aT == NULL)
  45. return FALSE;
  46. m_nAllocSize = size;
  47. m_aT = aT;
  48. }
  49. return TRUE;
  50. }
  51. BOOL Add(T& t)
  52. {
  53. if(m_nSize == m_nAllocSize)
  54. {
  55. int nNewAllocSize = (m_nAllocSize == 0) ? 1 : (m_nSize * 2);
  56. if (!GrowTo(nNewAllocSize))
  57. return FALSE;
  58. }
  59. m_nSize++;
  60. SetAtIndex(m_nSize - 1, t);
  61. return TRUE;
  62. }
  63. int AddN(T& t) // Adds the new item and returns its index
  64. {
  65. if (Add(t))
  66. return m_nSize - 1;
  67. else
  68. return -1;
  69. }
  70. BOOL Push(T& t)
  71. {
  72. return Add(t);
  73. }
  74. BOOL Pop(T& t)
  75. {
  76. if (m_nSize == 0)
  77. return FALSE;
  78. t = m_aT[m_nSize - 1];
  79. return RemoveAt(m_nSize - 1);
  80. }
  81. BOOL Remove(const T& t)
  82. {
  83. int nIndex = Find(t);
  84. if(nIndex == -1)
  85. return FALSE;
  86. return RemoveAt(nIndex);
  87. }
  88. BOOL RemoveAt(int nIndex)
  89. {
  90. if(nIndex >= m_nSize)
  91. return FALSE;
  92. //---- always call the dtr ----
  93. #if _MSC_VER >= 1200
  94. m_aT[nIndex].~T();
  95. #else
  96. T* MyT;
  97. MyT = &m_aT[nIndex];
  98. MyT->~T();
  99. #endif
  100. //---- if target entry is not at end, compact the array ----
  101. if(nIndex != (m_nSize - 1))
  102. {
  103. memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(T));
  104. }
  105. m_nSize--;
  106. return TRUE;
  107. }
  108. void RemoveAll()
  109. {
  110. if(m_aT != NULL)
  111. {
  112. for(int i = 0; i < m_nSize; i++) {
  113. #if _MSC_VER >= 1200
  114. m_aT[i].~T();
  115. #else
  116. T* MyT;
  117. MyT = &m_aT[i];
  118. MyT->~T();
  119. #endif
  120. }
  121. free(m_aT);
  122. m_aT = NULL;
  123. }
  124. m_nSize = 0;
  125. m_nAllocSize = 0;
  126. }
  127. T& operator[] (int nIndex) const
  128. {
  129. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  130. return m_aT[nIndex];
  131. }
  132. T* GetData() const
  133. {
  134. return m_aT;
  135. }
  136. // Implementation
  137. class Wrapper
  138. {
  139. public:
  140. Wrapper(T& _t) : t(_t)
  141. {
  142. }
  143. template <class _Ty>
  144. void *operator new(size_t, _Ty* p)
  145. {
  146. return p;
  147. }
  148. T t;
  149. };
  150. void SetAtIndex(int nIndex, T& t)
  151. {
  152. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  153. new(m_aT + nIndex) Wrapper(t);
  154. }
  155. int Find(const T& t) const
  156. {
  157. for(int i = 0; i < m_nSize; i++)
  158. {
  159. if(m_aT[i] == t)
  160. return i;
  161. }
  162. return -1; // not found
  163. }
  164. BOOL Parse(BYTE **ppRaw, int NumSize = 4)
  165. {
  166. if (!ppRaw || !*ppRaw)
  167. return FALSE;
  168. RemoveAll();
  169. // Get the number of elements from the raw data
  170. ULONG NumElems;
  171. switch (NumSize)
  172. {
  173. case 4:
  174. NumElems = MAKELONG(MAKEWORD((*ppRaw)[0], (*ppRaw)[1]), MAKEWORD((*ppRaw)[2], (*ppRaw)[3]));
  175. break;
  176. case 2:
  177. NumElems = MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
  178. break;
  179. case 1:
  180. NumElems = **ppRaw;
  181. break;
  182. default:
  183. return FALSE;
  184. }
  185. *ppRaw += NumSize;
  186. // Allocate space for the array
  187. if (!GrowTo(NumElems))
  188. return FALSE;
  189. // Copy in the elements
  190. memcpy(m_aT, *ppRaw, NumElems * sizeof(T));
  191. m_nSize = NumElems;
  192. // Advance the raw pointer past the array and number of elements field
  193. *ppRaw += NumElems * sizeof(T);
  194. return TRUE;
  195. }
  196. };
  197. // for arrays of simple types
  198. template <class T>
  199. class CWiaValArray : public CWiaArray< T >
  200. {
  201. public:
  202. BOOL Add(T t)
  203. {
  204. return CWiaArray< T >::Add(t);
  205. }
  206. BOOL Remove(T t)
  207. {
  208. return CWiaArray< T >::Remove(t);
  209. }
  210. T operator[] (int nIndex) const
  211. {
  212. return CWiaArray< T >::operator[](nIndex);
  213. }
  214. };
  215. // intended for small number of simple types or pointers
  216. template <class TKey, class TVal>
  217. class CWiaMap
  218. {
  219. public:
  220. TKey* m_aKey;
  221. TVal* m_aVal;
  222. int m_nSize;
  223. // Construction/destruction
  224. CWiaMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
  225. { }
  226. ~CWiaMap()
  227. {
  228. RemoveAll();
  229. }
  230. // Operations
  231. int GetSize() const
  232. {
  233. return m_nSize;
  234. }
  235. BOOL Add(TKey key, TVal val)
  236. {
  237. TKey* pKey;
  238. pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));
  239. if(pKey == NULL)
  240. return FALSE;
  241. m_aKey = pKey;
  242. TVal* pVal;
  243. pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));
  244. if(pVal == NULL)
  245. return FALSE;
  246. m_aVal = pVal;
  247. m_nSize++;
  248. SetAtIndex(m_nSize - 1, key, val);
  249. return TRUE;
  250. }
  251. BOOL Remove(TKey key)
  252. {
  253. int nIndex = FindKey(key);
  254. if(nIndex == -1)
  255. return FALSE;
  256. if(nIndex != (m_nSize - 1))
  257. {
  258. #if 0
  259. // This code seems to be causing problems. Since it's not
  260. // needed, ifdef it out for now.
  261. m_aKey[nIndex].~TKey();
  262. #if _MSC_VER >= 1200
  263. m_aVal[nIndex].~TVal();
  264. #else
  265. TVal * t1;
  266. t1 = &m_aVal[nIndex];
  267. t1->~TVal();
  268. #endif
  269. #endif
  270. memmove((void*)&m_aKey[nIndex], (void*)&m_aKey[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TKey));
  271. memmove((void*)&m_aVal[nIndex], (void*)&m_aVal[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TVal));
  272. }
  273. TKey* pKey;
  274. pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  275. if(pKey != NULL || m_nSize == 1)
  276. m_aKey = pKey;
  277. TVal* pVal;
  278. pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  279. if(pVal != NULL || m_nSize == 1)
  280. m_aVal = pVal;
  281. m_nSize--;
  282. return TRUE;
  283. }
  284. void RemoveAll()
  285. {
  286. if(m_aKey != NULL)
  287. {
  288. for(int i = 0; i < m_nSize; i++)
  289. {
  290. m_aKey[i].~TKey();
  291. #if _MSC_VER >= 1200
  292. m_aVal[i].~TVal();
  293. #else
  294. TVal * t1;
  295. t1 = &m_aVal[i];
  296. t1->~TVal();
  297. #endif
  298. }
  299. free(m_aKey);
  300. m_aKey = NULL;
  301. }
  302. if(m_aVal != NULL)
  303. {
  304. free(m_aVal);
  305. m_aVal = NULL;
  306. }
  307. m_nSize = 0;
  308. }
  309. BOOL SetAt(TKey key, TVal val)
  310. {
  311. int nIndex = FindKey(key);
  312. if(nIndex == -1)
  313. return FALSE;
  314. SetAtIndex(nIndex, key, val);
  315. return TRUE;
  316. }
  317. TVal Lookup(TKey key) const
  318. {
  319. int nIndex = FindKey(key);
  320. if(nIndex == -1)
  321. return NULL; // must be able to convert
  322. return GetValueAt(nIndex);
  323. }
  324. TKey ReverseLookup(TVal val) const
  325. {
  326. int nIndex = FindVal(val);
  327. if(nIndex == -1)
  328. return NULL; // must be able to convert
  329. return GetKeyAt(nIndex);
  330. }
  331. TKey& GetKeyAt(int nIndex) const
  332. {
  333. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  334. return m_aKey[nIndex];
  335. }
  336. TVal& GetValueAt(int nIndex) const
  337. {
  338. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  339. return m_aVal[nIndex];
  340. }
  341. // Implementation
  342. template <typename T>
  343. class Wrapper
  344. {
  345. public:
  346. Wrapper(T& _t) : t(_t)
  347. {
  348. }
  349. template <typename _Ty>
  350. void *operator new(size_t, _Ty* p)
  351. {
  352. return p;
  353. }
  354. T t;
  355. };
  356. void SetAtIndex(int nIndex, TKey& key, TVal& val)
  357. {
  358. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  359. new(m_aKey + nIndex) Wrapper<TKey>(key);
  360. new(m_aVal + nIndex) Wrapper<TVal>(val);
  361. }
  362. int FindKey(TKey& key) const
  363. {
  364. for(int i = 0; i < m_nSize; i++)
  365. {
  366. if(m_aKey[i] == key)
  367. return i;
  368. }
  369. return -1; // not found
  370. }
  371. int FindVal(TVal& val) const
  372. {
  373. for(int i = 0; i < m_nSize; i++)
  374. {
  375. if(m_aVal[i] == val)
  376. return i;
  377. }
  378. return -1; // not found
  379. }
  380. };
  381. #endif // TYPEUTIL__H_