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.

481 lines
9.9 KiB

  1. /*---------------------------------------------------------------------------
  2. FILE : PLEX.C
  3. AUTHOR: STOLEN FROM EXCEL modified by NavPal
  4. This file contains routines used to manipulate the PL (pronounced:
  5. "plex") structures.
  6. ----------------------------------------------------------------------------*/
  7. #include "priv.h"
  8. #pragma hdrstop
  9. /*-----------------------------------------------------------------------
  10. | FInRange
  11. | Simple little routine that tells you if a number lies within a
  12. | range.
  13. |
  14. |
  15. | Arguments:
  16. | w: Number to check
  17. | wFirst: First number in the range
  18. | wLast: Last number in the range
  19. |
  20. | Returns:
  21. | fTrue if the number is in range
  22. |
  23. | Keywords: in range check
  24. -----------------------------------------------------------------------*/
  25. BOOL FInRange(w, wFirst, wLast)
  26. int w;
  27. int wFirst, wLast;
  28. {
  29. Assert(wLast >= wFirst);
  30. return(w >= wFirst && w <= wLast);
  31. }
  32. #ifdef DEBUG
  33. /*----------------------------------------------------------------------------
  34. | FValidPl
  35. |
  36. | Checks for a valid PL structure.
  37. |
  38. | Arguments:
  39. | ppl PL to check
  40. |
  41. | Returns:
  42. | fTrue if the PL looks reasonable.
  43. ----------------------------------------------------------------------------*/
  44. BOOL FValidPl(pvPl)
  45. VOID *pvPl;
  46. {
  47. PL * ppl;
  48. ppl = (PL *) pvPl;
  49. if (ppl== NULL ||
  50. ppl->cbItem == 0 ||
  51. ppl->iMac < 0 ||
  52. ppl->iMax < 0 ||
  53. ppl->iMax < ppl->iMac)
  54. {
  55. return(fFalse);
  56. }
  57. return(fTrue);
  58. }
  59. #endif //DEBUG
  60. /*----------------------------------------------------------------------------
  61. | CbPlAlloc
  62. |
  63. | Returns amount of memory allocated to the given PL
  64. |
  65. | Arguments:
  66. | ppl PL to return info for.
  67. |
  68. | Returns:
  69. | memory allocated to the PL
  70. ----------------------------------------------------------------------------*/
  71. int CbPlAlloc(pvPl)
  72. VOID *pvPl;
  73. {
  74. PL * ppl;
  75. ppl = (PL *) pvPl;
  76. if (ppl == NULL)
  77. return(0);
  78. Assert(FValidPl(ppl));
  79. return(WAlign(cbPL + (ppl->iMax * ppl->cbItem)));
  80. }
  81. /*----------------------------------------------------------------------------
  82. | FreePpl
  83. |
  84. | Frees a PL.
  85. |
  86. | Arguments:
  87. | ppl PL to free
  88. |
  89. | Returns:
  90. | Nothing.
  91. ----------------------------------------------------------------------------*/
  92. void FreePpl(pvPl)
  93. VOID *pvPl;
  94. {
  95. Assert(FValidPl(pvPl));
  96. LocalFree(pvPl);
  97. }
  98. /*----------------------------------------------------------------------------
  99. | PplAlloc
  100. |
  101. | Allocates and initializes a PL.
  102. |
  103. | Arguments:
  104. | cbItem sizeof structure in the PL
  105. | dAlloc number of items to allocate at a time
  106. | iMax number of items in initial allocation
  107. |
  108. | Returns:
  109. | Pointer to PL.
  110. |
  111. | Notes:
  112. | returns NULL if OOM
  113. ----------------------------------------------------------------------------*/
  114. VOID *PplAlloc(cbItem, dAlloc, iMax)
  115. unsigned cbItem;
  116. int dAlloc;
  117. unsigned iMax;
  118. {
  119. PL *ppl;
  120. long cb;
  121. if (iMax > 32767) /* not too likely, but what the heck. */
  122. return(NULL);
  123. Assert((cbItem>=1 && cbItem<=65535u) && FInRange(dAlloc, 1, 31));
  124. cb = WAlign((long) cbPL + (long) cbItem * (long) iMax);
  125. ppl = (PL *) LocalAlloc( LPTR, cb );
  126. if(ppl==NULL)
  127. return(NULL);
  128. ppl->cbItem = cbItem;
  129. ppl->dAlloc = dAlloc;
  130. ppl->iMax = iMax;
  131. ppl->fUseCount = fFalse;
  132. Assert(FValidPl(ppl));
  133. return(ppl);
  134. }
  135. /*----------------------------------------------------------------------------
  136. | IAddPl
  137. |
  138. | Adds an item to a PL.
  139. |
  140. | Arguments:
  141. | pppl Pointer to PL. May change if reallocated.
  142. | pv New item to add.
  143. |
  144. | Returns:
  145. | Index of new item.
  146. |
  147. | Notes:
  148. | returns -1 if OOM
  149. ----------------------------------------------------------------------------*/
  150. int IAddPl(ppvPl, pv)
  151. VOID **ppvPl;
  152. VOID *pv;
  153. {
  154. int cbItem;
  155. int iMac;
  156. PL *ppl, *pplNew;
  157. ppl = *ppvPl;
  158. Assert(FValidPl(ppl));
  159. cbItem = ppl->cbItem;
  160. iMac = ppl->iMac;
  161. if (iMac == ppl->iMax)
  162. {
  163. pplNew = PplAlloc(cbItem, ppl->dAlloc, iMac + ppl->dAlloc);
  164. if(pplNew==NULL)
  165. return(-1);
  166. pplNew->fUseCount = ppl->fUseCount;
  167. CopyMemory( pplNew->rg, ppl->rg, iMac * cbItem);
  168. /* pplNew->iMac = iMac; /* This is not needed because hppl->iMac will be over-written later */
  169. FreePpl(ppl);
  170. *ppvPl = ppl = pplNew;
  171. }
  172. CopyMemory( &ppl->rg[iMac * cbItem], pv, cbItem );
  173. ppl->iMac = iMac + 1;
  174. Assert(FValidPl(*ppvPl));
  175. return(iMac);
  176. }
  177. /*----------------------------------------------------------------------------
  178. | RemovePl
  179. |
  180. | Removes an item from a PL.
  181. |
  182. | Arguments:
  183. | ppl PL to remove item from
  184. | i index of item to remove
  185. |
  186. | Returns:
  187. | fTrue if an item was removed (only fFalse for use count plexes).
  188. ----------------------------------------------------------------------------*/
  189. BOOL RemovePl(pvPl, i)
  190. VOID *pvPl;
  191. int i;
  192. {
  193. int iMac;
  194. int cbItem;
  195. BYTE *p;
  196. PL * ppl;
  197. ppl = (PL *) pvPl;
  198. Assert(FValidPl(ppl) && i < ppl->iMac);
  199. iMac = ppl->iMac;
  200. cbItem = ppl->cbItem;
  201. p = &ppl->rg[i * cbItem];
  202. if (i != iMac - 1)
  203. {
  204. CopyMemory( p, p+cbItem, (iMac - i - 1) * cbItem );
  205. }
  206. ppl->iMac = iMac - 1;
  207. Assert(FValidPl(ppl));
  208. return fTrue;
  209. }
  210. /*----------------------------------------------------------------------------
  211. | ILookupPl
  212. |
  213. | Searches a PL for an item.
  214. |
  215. | Arguments:
  216. | ppl PL to lookup into
  217. | p item to lookup
  218. | pfnSgn Comparison function
  219. |
  220. | Returns:
  221. | index of item, if found.
  222. | -1 if not found.
  223. ----------------------------------------------------------------------------*/
  224. int ILookupPl(pvPl, pvItem, pfnSgn)
  225. VOID *pvPl;
  226. VOID *pvItem;
  227. int (*pfnSgn)();
  228. {
  229. int i;
  230. BYTE *p;
  231. PL * ppl;
  232. ppl = (PL *) pvPl;
  233. if (ppl == NULL)
  234. return(-1);
  235. Assert(FValidPl(ppl));
  236. for (i = 0, p = ppl->rg; i < ppl->iMac; i++, p += ppl->cbItem)
  237. {
  238. if ((*(int (*)(void *, void *))pfnSgn)(p, pvItem) == sgnEQ)
  239. {
  240. return(i);
  241. }
  242. }
  243. return(-1);
  244. }
  245. /*----------------------------------------------------------------------------
  246. | PLookupPl
  247. |
  248. | Searches a PL for an item
  249. |
  250. | Arguments:
  251. | ppl PL to search
  252. | pItem item to search for
  253. | pfnSgn comparison function
  254. |
  255. | Returns:
  256. | Pointer to item, if found
  257. | Null, if not found
  258. ----------------------------------------------------------------------------*/
  259. VOID *PLookupPl(pvPl, pvItem, pfnSgn)
  260. VOID *pvPl;
  261. VOID *pvItem;
  262. int (*pfnSgn)();
  263. {
  264. int i;
  265. if ((i = ILookupPl(pvPl, pvItem, pfnSgn)) == -1)
  266. return(NULL);
  267. return(&((PL *)pvPl)->rg[i * ((PL *)pvPl)->cbItem]);
  268. }
  269. /*----------------------------------------------------------------------------
  270. | FLookupSortedPl
  271. |
  272. | Searches a sorted PL for an item.
  273. |
  274. | Arguments:
  275. | hppl PL to lookup into
  276. | hpItem Item to lookup
  277. | pi Index of found item (or insertion location if not)
  278. | pfnSgn Comparison function
  279. |
  280. | Returns:
  281. | index of item, if found.
  282. | index of location to insert if not found.
  283. ----------------------------------------------------------------------------*/
  284. int FLookupSortedPl(hpvPl, hpvItem, pi, pfnSgn)
  285. VOID *hpvPl;
  286. VOID *hpvItem;
  287. int *pi;
  288. int (*pfnSgn)();
  289. {
  290. int sgn;
  291. unsigned iMin, iMid, iMac;
  292. int cbItem;
  293. BYTE *hprg;
  294. BYTE *hpMid;
  295. PL * hppl;
  296. hppl = (PL *) hpvPl;
  297. if ((hppl)==NULL)
  298. {
  299. *pi = 0;
  300. return(fFalse);
  301. }
  302. Assert(FValidPl(hppl));
  303. Assert(!hppl->fUseCount);
  304. sgn = 1;
  305. cbItem = hppl->cbItem;
  306. iMin = iMid = 0;
  307. iMac = hppl->iMac;
  308. hprg = hppl->rg;
  309. while (iMin != iMac)
  310. {
  311. iMid = iMin + (iMac-iMin)/2;
  312. Assert(iMid != iMac);
  313. hpMid = hprg + iMid*cbItem;
  314. if ((sgn = (*(int (*)(void *, void *))pfnSgn)(hpMid, hpvItem)) == 0)
  315. break;
  316. /* Too low, look in upper interval */
  317. if (sgn < 0)
  318. iMin = ++iMid;
  319. /* Too high, look in lower interval */
  320. else
  321. iMac = iMid;
  322. }
  323. /* Not found, return index of location to insert it */
  324. *pi = iMid;
  325. return(sgn == 0);
  326. }
  327. /*----------------------------------------------------------------------------
  328. | IAddNewPl
  329. |
  330. | Adds an item to a PL, creating the PL if it's initially NULL.
  331. |
  332. | Arguments:
  333. | phppl pointer to PL
  334. | hp pointer to item to add
  335. | cbItem size of item
  336. |
  337. | Returns:
  338. | the index of item added, if successful
  339. | -1, if out-of-memory
  340. ----------------------------------------------------------------------------*/
  341. int IAddNewPl(phpvPl, hpv, cbItem)
  342. VOID **phpvPl;
  343. VOID *hpv;
  344. int cbItem;
  345. {
  346. int i;
  347. PL ** phppl;
  348. phppl = (PL **) phpvPl;
  349. Assert(((*phppl)==NULL) || !(*phppl)->fUseCount);
  350. i = -1;
  351. if ((*phppl)==NULL)
  352. {
  353. *phppl = PplAlloc(cbItem, 5, 5);
  354. }
  355. if((*phppl)!=NULL)
  356. {
  357. Assert((*phppl)->cbItem == cbItem);
  358. i = IAddPl((VOID **)phppl, hpv);
  359. }
  360. return(i);
  361. }
  362. /*----------------------------------------------------------------------------
  363. | IAddNewPlPos
  364. |
  365. | Inserts an item into a plex at a specific position.
  366. |
  367. | Arguments:
  368. | the index of the item added, if successful
  369. | -1 if out-of-memory
  370. ----------------------------------------------------------------------------*/
  371. int IAddNewPlPos(phpvPl, hpv, cbItem, i)
  372. VOID **phpvPl;
  373. VOID *hpv;
  374. int cbItem;
  375. int i;
  376. {
  377. BYTE *hpT;
  378. PL ** phppl;
  379. phppl = (PL **) phpvPl;
  380. Assert(((*phppl)==NULL) || !(*phppl)->fUseCount);
  381. if (IAddNewPl((VOID **)phppl, hpv, cbItem) == -1)
  382. return(-1);
  383. Assert(i < (*phppl)->iMac);
  384. hpT = &(*phppl)->rg[i * cbItem];
  385. // bltbh(hpT, hpT + cbItem, ((*phppl)->iMac - i - 1) * cbItem);
  386. // bltbh(hpv, hpT, cbItem);
  387. CopyMemory( hpT + cbItem, hpT, ((*phppl)->iMac - i - 1) * cbItem );
  388. CopyMemory( hpT, hpv, cbItem );
  389. Assert(FValidPl(*phppl));
  390. return(i);
  391. }
  392. int IAddPlSort(phpvPl, hpv, pfnSgn)
  393. VOID **phpvPl;
  394. VOID *hpv;
  395. int (*pfnSgn)();
  396. {
  397. int i;
  398. #ifdef DEBUG
  399. int iOld;
  400. #endif
  401. Assert((*phpvPl)!=NULL);
  402. if (FLookupSortedPl(*phpvPl, hpv, &i, pfnSgn))
  403. return(-1);
  404. #ifdef DEBUG
  405. iOld = i;
  406. #endif
  407. i = IAddNewPlPos(phpvPl, hpv, (*(PL **)phpvPl)->cbItem, i);
  408. #ifdef DEBUG
  409. Assert(i == -1 || i == iOld);
  410. #endif
  411. return(i);
  412. }