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.

416 lines
9.2 KiB

  1. /*++
  2. Copyright (C) 1999- Microsoft Corporation
  3. Module Name:
  4. wiatempl.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. //---- always call the dtr ----
  91. #if _MSC_VER >= 1200
  92. m_aT[nIndex].~T();
  93. #else
  94. T* MyT;
  95. MyT = &m_aT[nIndex];
  96. MyT->~T();
  97. #endif
  98. //---- if target entry is not at end, compact the array ----
  99. if(nIndex != (m_nSize - 1))
  100. {
  101. memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(T));
  102. }
  103. m_nSize--;
  104. return TRUE;
  105. }
  106. void RemoveAll()
  107. {
  108. if(m_aT != NULL)
  109. {
  110. for(int i = 0; i < m_nSize; i++) {
  111. #if _MSC_VER >= 1200
  112. m_aT[i].~T();
  113. #else
  114. T* MyT;
  115. MyT = &m_aT[i];
  116. MyT->~T();
  117. #endif
  118. }
  119. free(m_aT);
  120. m_aT = NULL;
  121. }
  122. m_nSize = 0;
  123. m_nAllocSize = 0;
  124. }
  125. T& operator[] (int nIndex) const
  126. {
  127. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  128. return m_aT[nIndex];
  129. }
  130. T* GetData() const
  131. {
  132. return m_aT;
  133. }
  134. // Implementation
  135. class Wrapper
  136. {
  137. public:
  138. Wrapper(T& _t) : t(_t)
  139. {
  140. }
  141. template <class _Ty>
  142. void *operator new(size_t, _Ty* p)
  143. {
  144. return p;
  145. }
  146. T t;
  147. };
  148. void SetAtIndex(int nIndex, T& t)
  149. {
  150. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  151. new(m_aT + nIndex) Wrapper(t);
  152. }
  153. int Find(const T& t) const
  154. {
  155. for(int i = 0; i < m_nSize; i++)
  156. {
  157. if(m_aT[i] == t)
  158. return i;
  159. }
  160. return -1; // not found
  161. }
  162. BOOL Parse(BYTE **ppRaw, int NumSize = 4)
  163. {
  164. if (!ppRaw || !*ppRaw)
  165. return FALSE;
  166. RemoveAll();
  167. // Get the number of elements from the raw data
  168. int NumElems;
  169. DWORD *pDword = (DWORD *) *ppRaw;
  170. WORD *pWord = (WORD *) *ppRaw;
  171. switch (NumSize)
  172. {
  173. case 4:
  174. NumElems = *pDword;
  175. break;
  176. case 2:
  177. NumElems = *pWord;
  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. m_aKey[nIndex].~TKey();
  259. #if _MSC_VER >= 1200
  260. m_aVal[nIndex].~TVal();
  261. #else
  262. TVal * t1;
  263. t1 = &m_aVal[nIndex];
  264. t1->~TVal();
  265. #endif
  266. memmove((void*)&m_aKey[nIndex], (void*)&m_aKey[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TKey));
  267. memmove((void*)&m_aVal[nIndex], (void*)&m_aVal[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TVal));
  268. }
  269. TKey* pKey;
  270. pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  271. if(pKey != NULL || m_nSize == 1)
  272. m_aKey = pKey;
  273. TVal* pVal;
  274. pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  275. if(pVal != NULL || m_nSize == 1)
  276. m_aVal = pVal;
  277. m_nSize--;
  278. return TRUE;
  279. }
  280. void RemoveAll()
  281. {
  282. if(m_aKey != NULL)
  283. {
  284. for(int i = 0; i < m_nSize; i++)
  285. {
  286. m_aKey[i].~TKey();
  287. #if _MSC_VER >= 1200
  288. m_aVal[i].~TVal();
  289. #else
  290. TVal * t1;
  291. t1 = &m_aVal[i];
  292. t1->~TVal();
  293. #endif
  294. }
  295. free(m_aKey);
  296. m_aKey = NULL;
  297. }
  298. if(m_aVal != NULL)
  299. {
  300. free(m_aVal);
  301. m_aVal = NULL;
  302. }
  303. m_nSize = 0;
  304. }
  305. BOOL SetAt(TKey key, TVal val)
  306. {
  307. int nIndex = FindKey(key);
  308. if(nIndex == -1)
  309. return FALSE;
  310. SetAtIndex(nIndex, key, val);
  311. return TRUE;
  312. }
  313. TVal Lookup(TKey key) const
  314. {
  315. int nIndex = FindKey(key);
  316. if(nIndex == -1)
  317. return NULL; // must be able to convert
  318. return GetValueAt(nIndex);
  319. }
  320. TKey ReverseLookup(TVal val) const
  321. {
  322. int nIndex = FindVal(val);
  323. if(nIndex == -1)
  324. return NULL; // must be able to convert
  325. return GetKeyAt(nIndex);
  326. }
  327. TKey& GetKeyAt(int nIndex) const
  328. {
  329. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  330. return m_aKey[nIndex];
  331. }
  332. TVal& GetValueAt(int nIndex) const
  333. {
  334. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  335. return m_aVal[nIndex];
  336. }
  337. // Implementation
  338. template <typename T>
  339. class Wrapper
  340. {
  341. public:
  342. Wrapper(T& _t) : t(_t)
  343. {
  344. }
  345. template <typename _Ty>
  346. void *operator new(size_t, _Ty* p)
  347. {
  348. return p;
  349. }
  350. T t;
  351. };
  352. void SetAtIndex(int nIndex, TKey& key, TVal& val)
  353. {
  354. ASSERT(nIndex >= 0 && nIndex < m_nSize);
  355. new(m_aKey + nIndex) Wrapper<TKey>(key);
  356. new(m_aVal + nIndex) Wrapper<TVal>(val);
  357. }
  358. int FindKey(TKey& key) const
  359. {
  360. for(int i = 0; i < m_nSize; i++)
  361. {
  362. if(m_aKey[i] == key)
  363. return i;
  364. }
  365. return -1; // not found
  366. }
  367. int FindVal(TVal& val) const
  368. {
  369. for(int i = 0; i < m_nSize; i++)
  370. {
  371. if(m_aVal[i] == val)
  372. return i;
  373. }
  374. return -1; // not found
  375. }
  376. };
  377. #endif // TYPEUTIL__H_