Windows NT 4.0 source code leak
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.

356 lines
17 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. splutil.hxx
  6. Abstract:
  7. Common utils.
  8. Author:
  9. Albert Ting (AlbertT) 29-May-1994
  10. Revision History:
  11. --*/
  12. #ifndef _SPLUTIL_HXX
  13. #define _SPLUTIL_HXX
  14. //
  15. // Double linked list. DLINK must be the same as DLINKBASE, except
  16. // with differnt constructors.
  17. //
  18. typedef struct DLINK {
  19. DLINK()
  20. { FLink = NULL; }
  21. DLINK* FLink;
  22. DLINK* BLink;
  23. } *PDLINK;
  24. typedef struct DLINKBASE {
  25. DLINKBASE()
  26. { FLink = BLink = (PDLINK)this; }
  27. DLINK* FLink;
  28. DLINK* BLink;
  29. } *PDLINKBASE;
  30. class TIter {
  31. public:
  32. PDLINK _pdlink;
  33. PDLINK _pdlBase;
  34. BOOL
  35. bValid()
  36. { return _pdlink != _pdlBase; }
  37. VOID
  38. vNext()
  39. { _pdlink = _pdlink->FLink; }
  40. VOID
  41. vPrev()
  42. { _pdlink = _pdlink->BLink; }
  43. operator PDLINK()
  44. { return _pdlink; }
  45. };
  46. VOID
  47. LinkListDump(
  48. PDLINK pHead,
  49. DWORD offset,
  50. LPCSTR pcszType,
  51. LPCSTR pcszName
  52. );
  53. /********************************************************************
  54. TBase has two linked lists of TLink.
  55. class TBase {
  56. DLINK_BASE( TLink, Lisk, Link );
  57. DLINK_BASE( TLink, Link2, Link2 );
  58. };
  59. class TLink {
  60. DLINK( TLink, Link );
  61. DLINK( TLink, Link2 );
  62. };
  63. //
  64. // Append pLink to the end of the Link2 list.
  65. //
  66. pBase->Link2_vAppend( pLink );
  67. //
  68. // Insert pLinkInsert right after pLinkMiddle.
  69. //
  70. pBase->Link_vInsert( pLinkMiddle, pLinkInsert );
  71. //
  72. // Get to the head.
  73. //
  74. pLinkHead = pBase->Link_pHead();
  75. pLinkHead = pLinkHead->Link_pNext();
  76. //
  77. // Using the iter class.
  78. //
  79. TIter Iter;
  80. for( Link_vIterInit( Iter ), Iter.vNext();
  81. Iter.bValid();
  82. Iter.vNext( )){
  83. //
  84. // Use pLink.
  85. //
  86. vLinkOperation( pLink );
  87. }
  88. ********************************************************************/
  89. #define DLINK_BASE( type, name, linkname ) \
  90. VOID name##_vReset() \
  91. { pdl##name()->FLink = pdl##name()->BLink = pdl##name(); } \
  92. \
  93. PDLINK name##_pdlHead() const \
  94. { return pdl##name()->FLink; } \
  95. \
  96. PDLINK name##_pdlBase() const \
  97. { return pdl##name(); } \
  98. \
  99. type* name##_pHead( VOID ) const \
  100. { \
  101. return name##_bValid( name##_pdlHead() ) ? \
  102. (type*)((PBYTE)name##_pdlHead() - OFFSETOF( type, \
  103. _dl##linkname )) : \
  104. NULL; \
  105. } \
  106. \
  107. BOOL name##_bValid( PDLINK pdlink ) const \
  108. { return pdlink != pdl##name(); } \
  109. \
  110. VOID name##_vAdd( type* pType ) \
  111. { name##_vInsert( pdl##name(), pType->pdl##linkname( )); } \
  112. \
  113. VOID name##_vAppend( type* pType ) \
  114. { name##_vInsert( pdl##name()->BLink, pType->pdl##linkname( )); } \
  115. \
  116. VOID name##_vInsert( PDLINK pdlink1, type* pType2 ) \
  117. { name##_vInsert( pdlink1, pType2->pdl##linkname() ); } \
  118. \
  119. VOID name##_vInsert( PDLINK pdlink1, PDLINK pdlink2 ) \
  120. { \
  121. SPLASSERT( !pdlink2->FLink ); \
  122. pdlink1->FLink->BLink = pdlink2; \
  123. \
  124. pdlink2->BLink = pdlink1; \
  125. pdlink2->FLink = pdlink1->FLink; \
  126. \
  127. pdlink1->FLink = pdlink2; \
  128. } \
  129. \
  130. VOID name##_vInsertBefore( PDLINK pdlink1, type* pType2 ) \
  131. { name##_vInsertBefore( pdlink1, pType2->pdl##linkname() ); } \
  132. \
  133. VOID name##_vInsertBefore( PDLINK pdlink1, PDLINK pdlink2 ) \
  134. { \
  135. SPLASSERT( !pdlink2->FLink ); \
  136. pdlink1->BLink->FLink = pdlink2; \
  137. \
  138. pdlink2->FLink = pdlink1; \
  139. pdlink2->BLink = pdlink1->BLink; \
  140. \
  141. pdlink1->BLink = pdlink2; \
  142. } \
  143. \
  144. VOID name##_vDelink( type* pType ) \
  145. { name##_vDelink( pType->pdl##linkname( )); } \
  146. \
  147. VOID name##_vDelink( PDLINK pdlink ) \
  148. { \
  149. pdlink->FLink->BLink = pdlink->BLink; \
  150. pdlink->BLink->FLink = pdlink->FLink; \
  151. pdlink->FLink = NULL; \
  152. } \
  153. \
  154. type* name##_pFind( type* pType ) const \
  155. { \
  156. PDLINK pdlinkT; \
  157. PDLINK pdlink = pType->pdl##linkname(); \
  158. \
  159. for( pdlinkT = name##_pdlHead(); \
  160. name##_bValid( pdlinkT ); \
  161. pdlinkT = pdlinkT->FLink ){ \
  162. \
  163. if( pType->pdl##linkname() == pdlinkT ) \
  164. return (type*)((PBYTE)pdlink - OFFSETOF( type, \
  165. _dl##linkname )); \
  166. } \
  167. return NULL; \
  168. } \
  169. \
  170. PDLINK name##_pdlFind( PDLINK pdlink ) const \
  171. { \
  172. PDLINK pdlinkT; \
  173. for( pdlinkT = name##_pdlHead(); \
  174. name##_bValid( pdlinkT ); \
  175. pdlinkT = pdlinkT->FLink ){ \
  176. \
  177. if( pdlink == pdlinkT ) \
  178. return pdlink; \
  179. } \
  180. return NULL; \
  181. } \
  182. \
  183. PDLINK name##_pdlGetByIndex( UINT uIndex ) const \
  184. { \
  185. PDLINK pdlink; \
  186. for( pdlink = name##_pdlHead(); \
  187. uIndex; \
  188. uIndex--, pdlink = pdlink->FLink ){ \
  189. \
  190. SPLASSERT( name##_bValid( pdlink )); \
  191. } \
  192. return pdlink; \
  193. } \
  194. \
  195. type* name##_pGetByIndex( UINT uIndex ) const \
  196. { \
  197. PDLINK pdlink; \
  198. for( pdlink = name##_pdlHead(); \
  199. uIndex; \
  200. uIndex--, pdlink = pdlink->FLink ){ \
  201. \
  202. SPLASSERT( name##_bValid( pdlink )); \
  203. } \
  204. return name##_pConvert( pdlink ); \
  205. } \
  206. \
  207. VOID name##_vDump( VOID ) const \
  208. { \
  209. LinkListDump( pdl##name(), \
  210. OFFSETOF( type, _dl##linkname ), \
  211. #type, \
  212. #name ); \
  213. } \
  214. \
  215. static PDLINK name##_pdlNext( PDLINK pdlink ) \
  216. { return pdlink->FLink; } \
  217. \
  218. static type* name##_pConvert( PDLINK pdlink ) \
  219. { return (type*)( (PBYTE)pdlink - OFFSETOF( type, _dl##linkname )); } \
  220. \
  221. PDLINK pdl##name( VOID ) const \
  222. { return (PDLINK)&_dlb##name; } \
  223. \
  224. BOOL name##_bEmpty() const \
  225. { return pdl##name()->FLink == pdl##name(); } \
  226. \
  227. VOID name##_vIterInit( TIter& Iter ) const \
  228. { Iter._pdlBase = Iter._pdlink = (PDLINK)&_dlb##name; } \
  229. \
  230. DLINKBASE _dlb##name;
  231. \
  232. #define DLINK( type, name ) \
  233. PDLINK pdl##name() \
  234. { return &_dl##name; } \
  235. \
  236. VOID name##_vDelinkSelf( VOID ) \
  237. { \
  238. _dl##name.FLink->BLink = _dl##name.BLink; \
  239. _dl##name.BLink->FLink = _dl##name.FLink; \
  240. _dl##name.FLink = NULL; \
  241. } \
  242. \
  243. BOOL name##_bLinked() const \
  244. { return _dl##name.FLink != NULL; } \
  245. \
  246. PDLINK name##_pdlNext( VOID ) const \
  247. { return _dl##name.FLink; } \
  248. \
  249. PDLINK name##_pdlPrev( VOID ) const \
  250. { return _dl##name.BLink; } \
  251. \
  252. type* name##_pNext( VOID ) const \
  253. { return name##_pConvert( _dl##name.FLink ); } \
  254. \
  255. type* name##_pPrev( VOID ) const \
  256. { return name##_pConvert( _dl##name.BLink ); } \
  257. \
  258. static type* name##_pConvert( PDLINK pdlink ) \
  259. { return (type*)( (PBYTE)pdlink - OFFSETOF( type, _dl##name )); } \
  260. \
  261. DLINK _dl##name
  262. //
  263. // Generic MEntry class that allows objects to be stored on a list
  264. // and searched by name.
  265. //
  266. class MEntry {
  267. SIGNATURE( 'entr' )
  268. public:
  269. DLINK( MEntry, Entry );
  270. TString _strName;
  271. BOOL bValid()
  272. {
  273. return _strName.bValid();
  274. }
  275. static MEntry* pFindEntry( PDLINK pdlink, LPCTSTR pszName );
  276. };
  277. #define ENTRY_BASE( type, name ) \
  278. friend MEntry; \
  279. type* name##_pFindByName( LPCTSTR pszName ) const \
  280. { \
  281. MEntry* pEntry = MEntry::pFindEntry( name##_pdlBase(), pszName ); \
  282. return pEntry ? (type*)pEntry : NULL; \
  283. } \
  284. static type* name##_pConvertEntry( PDLINK pdlink ) \
  285. { \
  286. return (type*)name##_pConvert( pdlink ); \
  287. } \
  288. DLINK_BASE( MEntry, name, Entry )
  289. #define DELETE_ENTRY_LIST( type, name ) \
  290. { \
  291. PDLINK pdlink; \
  292. type* pType; \
  293. \
  294. for( pdlink = name##_pdlHead(); name##_bValid( pdlink ); ){ \
  295. \
  296. pType = name##_pConvertEntry( pdlink ); \
  297. pdlink = name##_pdlNext( pdlink ); \
  298. \
  299. pType->vDelete(); \
  300. } \
  301. }
  302. #endif // ndef _SPLUTIL_HXX