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.

1160 lines
34 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. /* File: dynarray.cpp
  3. Description: Wrapper classes around the DPA_xxxxx and DSA_xxxxx functions
  4. provided by the common control's library. The classes add value by
  5. providing multi-threaded protection, iterators and automatic cleanup
  6. semantics.
  7. Revision History:
  8. Date Description Programmer
  9. -------- --------------------------------------------------- ----------
  10. 06/14/96 Initial creation. BrianAu
  11. 09/03/96 Added exception handling. BrianAu
  12. */
  13. ///////////////////////////////////////////////////////////////////////////////
  14. #include "pch.h" // PCH
  15. #pragma hdrstop
  16. #include "dynarray.h"
  17. ///////////////////////////////////////////////////////////////////////////////
  18. /* Function: PointerList::PointerList
  19. Description: Constructor.
  20. Arguments:
  21. cItemGrow - Number of items to grow list when expansion is required.
  22. Default value is 0 which causes DPA to use 8.
  23. Returns: Nothing.
  24. Exception: Throws OutOfMemory.
  25. Revision History:
  26. Date Description Programmer
  27. -------- --------------------------------------------------- ----------
  28. 09/03/96 Initial creation. BrianAu
  29. 02/21/97 Added cItemGrow argument. BrianAu
  30. */
  31. ///////////////////////////////////////////////////////////////////////////////
  32. PointerList::PointerList(
  33. INT cItemGrow
  34. )
  35. : m_hdpa(NULL)
  36. {
  37. if (!InitializeCriticalSectionAndSpinCount(&m_cs, 0))
  38. {
  39. throw CAllocException();
  40. }
  41. if (NULL == (m_hdpa = DPA_CreateEx(cItemGrow, NULL)))
  42. {
  43. DeleteCriticalSection(&m_cs);
  44. throw CAllocException();
  45. }
  46. }
  47. ///////////////////////////////////////////////////////////////////////////////
  48. /* Function: PointerList::~PointerList
  49. Description: Destructor. Destroys the DPA and closes the mutex handle.
  50. Arguments: None.
  51. Returns: Nothing.
  52. Revision History:
  53. Date Description Programmer
  54. -------- --------------------------------------------------- ----------
  55. 06/14/96 Initial creation. BrianAu
  56. */
  57. ///////////////////////////////////////////////////////////////////////////////
  58. PointerList::~PointerList(
  59. VOID
  60. )
  61. {
  62. Lock();
  63. if (NULL != m_hdpa)
  64. DPA_Destroy(m_hdpa);
  65. ReleaseLock();
  66. DeleteCriticalSection(&m_cs);
  67. }
  68. ///////////////////////////////////////////////////////////////////////////////
  69. /* Function: PointerList::Count
  70. Description: Returns the number of elements in the list.
  71. Arguments: None.
  72. Returns: Count of elements in list.
  73. Revision History:
  74. Date Description Programmer
  75. -------- --------------------------------------------------- ----------
  76. 06/14/96 Initial creation. BrianAu
  77. */
  78. ///////////////////////////////////////////////////////////////////////////////
  79. UINT
  80. PointerList::Count(
  81. VOID
  82. )
  83. {
  84. UINT n = 0;
  85. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  86. DBGASSERT((NULL != m_hdpa));
  87. n = DPA_GetPtrCount(m_hdpa);
  88. return n;
  89. }
  90. ///////////////////////////////////////////////////////////////////////////////
  91. /* Function: PointerList::Insert
  92. Description: Inserts a pointer into the pointer list at a given index.
  93. If the index is beyond the upper bounds of the array, the array
  94. is extended by one and the item is appended to the list.
  95. Arguments:
  96. pvItem - Pointer value to add to list.
  97. index - List index where pointer is to be inserted. All following
  98. items are shifted to one index higher. The list automatically
  99. grows to accomodate as required.
  100. Returns: Nothing.
  101. Exceptions: OutOfMemory.
  102. Revision History:
  103. Date Description Programmer
  104. -------- --------------------------------------------------- ----------
  105. 06/14/96 Initial creation. BrianAu
  106. 09/03/96 Added exception handling. BrianAu
  107. */
  108. ///////////////////////////////////////////////////////////////////////////////
  109. VOID
  110. PointerList::Insert(
  111. LPVOID pvItem,
  112. UINT index
  113. )
  114. {
  115. DBGASSERT((NULL != pvItem));
  116. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  117. DBGASSERT((NULL != m_hdpa));
  118. if (DPA_InsertPtr(m_hdpa, index, pvItem) < 0)
  119. {
  120. throw CAllocException();
  121. }
  122. }
  123. ///////////////////////////////////////////////////////////////////////////////
  124. /* Function: PointerList::Replace
  125. Description: Replaces a pointer in the pointer list at a given index.
  126. If the index is beyond the upper bounds of the array, the array
  127. is extended by one and the item is appended to the list.
  128. Arguments:
  129. pvItem - Pointer value to add to list.
  130. index - List index where pointer is to be replaced.
  131. Returns:
  132. TRUE - Success.
  133. FALSE - Invalid index or empty container.
  134. Revision History:
  135. Date Description Programmer
  136. -------- --------------------------------------------------- ----------
  137. 06/14/96 Initial creation. BrianAu
  138. */
  139. ///////////////////////////////////////////////////////////////////////////////
  140. BOOL
  141. PointerList::Replace(
  142. LPVOID pvItem,
  143. UINT index
  144. )
  145. {
  146. DBGASSERT((NULL != pvItem));
  147. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  148. DBGASSERT((NULL != m_hdpa));
  149. return DPA_SetPtr(m_hdpa, index, pvItem);
  150. }
  151. ///////////////////////////////////////////////////////////////////////////////
  152. /* Function: PointerList::Append
  153. Description: Appends a pointer to the end of the list.
  154. Arguments:
  155. pvItem - Pointer value to add to list.
  156. Returns: Nothing.
  157. Exceptions: OutOfMemory.
  158. Revision History:
  159. Date Description Programmer
  160. -------- --------------------------------------------------- ----------
  161. 06/14/96 Initial creation. BrianAu
  162. 09/03/96 Added exception handling. BrianAu
  163. */
  164. ///////////////////////////////////////////////////////////////////////////////
  165. VOID
  166. PointerList::Append(
  167. LPVOID pvItem
  168. )
  169. {
  170. DBGASSERT((NULL != pvItem));
  171. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  172. //
  173. // Yes, this is correct. We're "inserting" an item to append something
  174. // to the list. This saves a ( count - 1 ) calculation.
  175. //
  176. DBGASSERT((NULL != m_hdpa));
  177. Insert(pvItem, DPA_GetPtrCount(m_hdpa));
  178. }
  179. ///////////////////////////////////////////////////////////////////////////////
  180. /* Function: PointerList::Remove
  181. Description: Removes a pointer from the list at a given index.
  182. Arguments:
  183. ppvItem - Address of variable to contain removed pointer value.
  184. index - List index where pointer is to be removed. All following
  185. items are shifted to one index lower.
  186. Returns:
  187. TRUE - Success.
  188. FASLE - Index is invalid (or container is empty).
  189. Revision History:
  190. Date Description Programmer
  191. -------- --------------------------------------------------- ----------
  192. 06/14/96 Initial creation. BrianAu
  193. */
  194. ///////////////////////////////////////////////////////////////////////////////
  195. BOOL
  196. PointerList::Remove(
  197. LPVOID *ppvItem,
  198. UINT index
  199. )
  200. {
  201. DBGASSERT((NULL != ppvItem));
  202. DBGASSERT((NULL != m_hdpa));
  203. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  204. *ppvItem = DPA_DeletePtr(m_hdpa, index);
  205. if (NULL == *ppvItem)
  206. return FALSE;
  207. return TRUE;
  208. }
  209. ///////////////////////////////////////////////////////////////////////////////
  210. /* Function: PointerList::RemoveLast
  211. Description: Removes the last pointer from the list.
  212. Arguments:
  213. ppvItem - Address of variable to contain removed pointer value.
  214. All following items are shifted to one index lower.
  215. Returns:
  216. TRUE - Success.
  217. FALSE - Container is emtpy.
  218. Revision History:
  219. Date Description Programmer
  220. -------- --------------------------------------------------- ----------
  221. 06/14/96 Initial creation. BrianAu
  222. */
  223. ///////////////////////////////////////////////////////////////////////////////
  224. BOOL
  225. PointerList::RemoveLast(
  226. LPVOID *ppvItem
  227. )
  228. {
  229. DBGASSERT((NULL != ppvItem));
  230. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  231. if (0 == Count())
  232. return FALSE;
  233. Remove(ppvItem, Count() - 1);
  234. return TRUE;
  235. }
  236. ///////////////////////////////////////////////////////////////////////////////
  237. /* Function: PointerList::Retrieve
  238. Description: Retrieve a pointer from the list at a given index.
  239. The pointer value is merely retrieved and not removed from the list.
  240. Arguments:
  241. ppvItem - Address of variable to contain retrieved pointer value.
  242. index - List index where pointer is to be retrieved.
  243. Returns:
  244. TRUE - Success.
  245. FALSE - Invalid index or container is empty.
  246. Revision History:
  247. Date Description Programmer
  248. -------- --------------------------------------------------- ----------
  249. 06/14/96 Initial creation. BrianAu
  250. */
  251. ///////////////////////////////////////////////////////////////////////////////
  252. BOOL
  253. PointerList::Retrieve(
  254. LPVOID *ppvItem,
  255. UINT index
  256. )
  257. {
  258. DBGASSERT((NULL != ppvItem));
  259. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  260. DBGASSERT((NULL != m_hdpa));
  261. *ppvItem = DPA_GetPtr(m_hdpa, index);
  262. if (NULL == *ppvItem)
  263. return FALSE;
  264. return TRUE;
  265. }
  266. ///////////////////////////////////////////////////////////////////////////////
  267. /* Function: PointerList::RetrieveLast
  268. Description: Retrieves the last pointer from the list.
  269. Arguments:
  270. ppvItem - Address of variable to contain retrieved pointer value.
  271. Returns:
  272. TRUE - Success.
  273. FALSE - Container is empty.
  274. Revision History:
  275. Date Description Programmer
  276. -------- --------------------------------------------------- ----------
  277. 06/14/96 Initial creation. BrianAu
  278. 09/03/96 Added exception handling. BrianAu
  279. */
  280. ///////////////////////////////////////////////////////////////////////////////
  281. BOOL
  282. PointerList::RetrieveLast(
  283. LPVOID *ppvItem
  284. )
  285. {
  286. DBGASSERT((NULL != ppvItem));
  287. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  288. if (0 == Count())
  289. return FALSE;
  290. Retrieve(ppvItem, Count() - 1);
  291. return TRUE;
  292. }
  293. ///////////////////////////////////////////////////////////////////////////////
  294. /* Function: PointerList::FindIndex
  295. Description: Returns the list index associated with a given pointer
  296. value. If duplicates exist, the index of the first item is returned.
  297. Arguments:
  298. pvItem - Pointer value of item to be found.
  299. pIndex - Address of index variable to hold resulting index.
  300. Returns:
  301. TRUE = Success
  302. FALSE = Item not found in list.
  303. Revision History:
  304. Date Description Programmer
  305. -------- --------------------------------------------------- ----------
  306. 06/14/96 Initial creation. BrianAu
  307. 09/03/96 Changed returned value to BOOL. BrianAu
  308. */
  309. ///////////////////////////////////////////////////////////////////////////////
  310. BOOL
  311. PointerList::FindIndex(
  312. LPVOID pvItem,
  313. INT *pIndex
  314. )
  315. {
  316. INT i = -1;
  317. DBGASSERT((NULL != pIndex));
  318. DBGASSERT((NULL != pvItem));
  319. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  320. DBGASSERT((NULL != m_hdpa));
  321. i = *pIndex = DPA_GetPtrIndex(m_hdpa, pvItem);
  322. if (-1 == i)
  323. return FALSE;
  324. return TRUE;
  325. }
  326. ///////////////////////////////////////////////////////////////////////////////
  327. /* Function: PointerList::Sort
  328. Description: Sorts the list given a comparison function.
  329. Arguments:
  330. pfnCompare - Address of comparison callback.
  331. lParam - 32-bit parameter passed to the callback.
  332. Returns:
  333. TRUE = Success
  334. FALSE = Item not found in list.
  335. Revision History:
  336. Date Description Programmer
  337. -------- --------------------------------------------------- ----------
  338. 02/21/97 Initial creation. BrianAu
  339. */
  340. ///////////////////////////////////////////////////////////////////////////////
  341. BOOL
  342. PointerList::Sort(
  343. PFNDPACOMPARE pfnCompare,
  344. LPARAM lParam
  345. )
  346. {
  347. DBGASSERT((NULL != pfnCompare));
  348. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  349. DBGASSERT((NULL != m_hdpa));
  350. DBGASSERT((NULL != pfnCompare));
  351. return DPA_Sort(m_hdpa, pfnCompare, lParam);
  352. }
  353. ///////////////////////////////////////////////////////////////////////////////
  354. /* Function: PointerList::Search
  355. Description: Searches the list for a given item.
  356. Arguments:
  357. pvKey - Address of key item used for search.
  358. pfnCompare - Address of comparison callback.
  359. uOptions - Options controlling sort operation.
  360. DPAS_SORTED = Array is already sorted.
  361. Will use binary search.
  362. DPAS_INSERTBEFORE = If no exact match is found, return index of
  363. previous best match.
  364. DPAS_INSERTAFTER = If no exact match is found, return index of
  365. next best match.
  366. iStart - Index of where to start search. 0 for start of list.
  367. lParam - 32-bit parameter passed to the callback.
  368. Returns: Index of found item or -1 if none found.
  369. Revision History:
  370. Date Description Programmer
  371. -------- --------------------------------------------------- ----------
  372. 02/21/97 Initial creation. BrianAu
  373. */
  374. ///////////////////////////////////////////////////////////////////////////////
  375. INT
  376. PointerList::Search(
  377. LPVOID pvKey,
  378. PFNDPACOMPARE pfnCompare,
  379. UINT uOptions,
  380. INT iStart,
  381. LPARAM lParam
  382. )
  383. {
  384. DBGASSERT((NULL != pfnCompare));
  385. AutoLockCs lock(m_cs); // Get lock on container. Will automatically release.
  386. DBGASSERT((NULL != m_hdpa));
  387. DBGASSERT((NULL != pvKey));
  388. DBGASSERT((NULL != pfnCompare));
  389. return DPA_Search(m_hdpa, pvKey, iStart, pfnCompare, lParam, uOptions);
  390. }
  391. ///////////////////////////////////////////////////////////////////////////////
  392. /* Function: PointerListIterator::operator =
  393. Description: Assignment for PointerListIterator.
  394. Arguments:
  395. rhs - Reference to constant iterator that is the rhs of the assignment.
  396. Returns:
  397. Returns a reference to "this" iterator object following the assignment.
  398. Revision History:
  399. Date Description Programmer
  400. -------- --------------------------------------------------- ----------
  401. 02/27/97 Initial creation. BrianAu
  402. */
  403. ///////////////////////////////////////////////////////////////////////////////
  404. PointerListIterator&
  405. PointerListIterator::operator = (
  406. const PointerListIterator& rhs
  407. )
  408. {
  409. if (this != &rhs)
  410. {
  411. m_pList = rhs.m_pList;
  412. m_Index = rhs.m_Index;
  413. }
  414. return *this;
  415. }
  416. ///////////////////////////////////////////////////////////////////////////////
  417. /* Function: PointerListIterator::Advance
  418. Description: Both the Next() and Prev() iterator functions call this
  419. one function. It handles the actual iteration.
  420. Arguments:
  421. ppvOut - Address of pointer variable to contain the value of the
  422. pointer at the "current" iterator location. The iterator is
  423. advance (or retreated) after the pointer value is copied to the
  424. destination.
  425. bForward - TRUE = Advance toward end of list.
  426. FALSE = Advance toward front of list.
  427. Returns:
  428. NO_ERROR - Iterator advanced. Returned pointer is valid.
  429. E_FAIL - Iterator already at begining or end of list. Returned
  430. pointer will be NULL.
  431. Revision History:
  432. Date Description Programmer
  433. -------- --------------------------------------------------- ----------
  434. 06/14/96 Initial creation. BrianAu
  435. */
  436. ///////////////////////////////////////////////////////////////////////////////
  437. HRESULT
  438. PointerListIterator::Advance(
  439. LPVOID *ppvOut,
  440. BOOL bForward
  441. )
  442. {
  443. LPVOID pv = NULL;
  444. HRESULT hResult = NO_ERROR;
  445. DBGASSERT((NULL != ppvOut));
  446. m_pList->Lock();
  447. if (0 < m_pList->Count() && m_Index != EndOfList)
  448. {
  449. //
  450. // Get pointer value at index "m_Index".
  451. //
  452. DBGASSERT((NULL != m_pList->m_hdpa));
  453. pv = DPA_GetPtr(m_pList->m_hdpa, m_Index);
  454. if (bForward)
  455. {
  456. //
  457. // Advance iterator index.
  458. //
  459. if ((UINT)(++m_Index) == m_pList->Count())
  460. m_Index = EndOfList;
  461. }
  462. else
  463. {
  464. //
  465. // Retreat iterator index.
  466. //
  467. m_Index--; // Will be -1 (EndOfList) if currently 0.
  468. }
  469. }
  470. else
  471. hResult = E_FAIL;
  472. m_pList->ReleaseLock();
  473. *ppvOut = pv; // Return pointer value.
  474. return hResult;
  475. }
  476. ///////////////////////////////////////////////////////////////////////////////
  477. /* Function: StructureList::StructureList
  478. Description: Constructor.
  479. Arguments:
  480. cbItem - Size of each item in bytes.
  481. cItemGrow - Number of items to grow array at each expansion.
  482. Returns: Nothing.
  483. Exceptions: OutOfMemory
  484. Revision History:
  485. Date Description Programmer
  486. -------- --------------------------------------------------- ----------
  487. 09/06/96 Initial creation. BrianAu
  488. */
  489. ///////////////////////////////////////////////////////////////////////////////
  490. StructureList::StructureList(
  491. INT cbItem,
  492. INT cItemGrow
  493. )
  494. {
  495. if (!InitializeCriticalSectionAndSpinCount(&m_cs, 0))
  496. {
  497. throw CAllocException();
  498. }
  499. if (NULL == (m_hdsa = DSA_Create(cbItem, cItemGrow)))
  500. {
  501. DeleteCriticalSection(&m_cs);
  502. throw CAllocException();
  503. }
  504. }
  505. ///////////////////////////////////////////////////////////////////////////////
  506. /* Function: StructureList::~StructureList
  507. Description: Destructor. Destroys the DSA and closes the mutex handle.
  508. Arguments: None.
  509. Returns: Nothing.
  510. Revision History:
  511. Date Description Programmer
  512. -------- --------------------------------------------------- ----------
  513. 06/24/96 Initial creation. BrianAu
  514. */
  515. ///////////////////////////////////////////////////////////////////////////////
  516. StructureList::~StructureList(void)
  517. {
  518. Lock();
  519. if (NULL != m_hdsa)
  520. DSA_Destroy(m_hdsa);
  521. ReleaseLock();
  522. DeleteCriticalSection(&m_cs);
  523. }
  524. ///////////////////////////////////////////////////////////////////////////////
  525. /* Function: StructureListIterator::operator =
  526. Description: Assignment for StructureListIterator.
  527. Arguments:
  528. rhs - Reference to constant iterator that is the rhs of the assignment.
  529. Returns:
  530. Returns a reference to "this" iterator object following the assignment.
  531. Revision History:
  532. Date Description Programmer
  533. -------- --------------------------------------------------- ----------
  534. 02/27/97 Initial creation. BrianAu
  535. */
  536. ///////////////////////////////////////////////////////////////////////////////
  537. StructureListIterator&
  538. StructureListIterator::operator = (
  539. const StructureListIterator& rhs
  540. )
  541. {
  542. if (this != &rhs)
  543. {
  544. m_pList = rhs.m_pList;
  545. m_Index = rhs.m_Index;
  546. }
  547. return *this;
  548. }
  549. ///////////////////////////////////////////////////////////////////////////////
  550. /* Function: StructureList::Count
  551. Description: Returns the number of elements in the list.
  552. Arguments: None.
  553. Returns: Count of elements in list.
  554. Revision History:
  555. Date Description Programmer
  556. -------- --------------------------------------------------- ----------
  557. 06/24/96 Initial creation. BrianAu
  558. */
  559. ///////////////////////////////////////////////////////////////////////////////
  560. UINT StructureList::Count(VOID)
  561. {
  562. UINT n = 0;
  563. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  564. DBGASSERT((NULL != m_hdsa));
  565. n = DSA_GetItemCount(m_hdsa);
  566. return n;
  567. }
  568. ///////////////////////////////////////////////////////////////////////////////
  569. /* Function: StructureList::Insert
  570. Description: Insert an item into the Structure list at a given index.
  571. If the index is beyond the upper bounds of the array, the array
  572. is extended by one and the item is appended to the list.
  573. Arguments:
  574. pvItem - Address of item to add to list.
  575. index - List index where item is to be inserted. All following
  576. items are shifted to one index higher. The list automatically
  577. grows to accomodate as required.
  578. Returns: Nothing.
  579. Exceptions: OutOfMemory.
  580. Revision History:
  581. Date Description Programmer
  582. -------- --------------------------------------------------- ----------
  583. 06/24/96 Initial creation. BrianAu
  584. 09/06/96 Added exception handling. BrianAu
  585. */
  586. ///////////////////////////////////////////////////////////////////////////////
  587. VOID
  588. StructureList::Insert(
  589. LPVOID pvItem,
  590. UINT index
  591. )
  592. {
  593. DBGASSERT((NULL != pvItem));
  594. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  595. DBGASSERT((NULL != m_hdsa));
  596. if (DSA_InsertItem(m_hdsa, index, pvItem) < 0)
  597. {
  598. throw CAllocException();
  599. }
  600. }
  601. ///////////////////////////////////////////////////////////////////////////////
  602. /* Function: StructureList::Replace
  603. Description: Replaces an item in the Structure list at a given index.
  604. If the index is beyond the upper bounds of the array, the array
  605. is extended by one and the item is appended to the list.
  606. Arguments:
  607. pvItem - Address of item to replace existing item.
  608. index - List index where item is to be replaced.
  609. Returns:
  610. TRUE - Success.
  611. FALSE - Invalid index or empty container.
  612. Revision History:
  613. Date Description Programmer
  614. -------- --------------------------------------------------- ----------
  615. 06/24/96 Initial creation. BrianAu
  616. */
  617. ///////////////////////////////////////////////////////////////////////////////
  618. BOOL
  619. StructureList::Replace(
  620. LPVOID pvItem,
  621. UINT index
  622. )
  623. {
  624. DBGASSERT((NULL != pvItem));
  625. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  626. DBGASSERT((NULL != m_hdsa));
  627. return DSA_SetItem(m_hdsa, index, pvItem);
  628. }
  629. ///////////////////////////////////////////////////////////////////////////////
  630. /* Function: StructureList::Append
  631. Description: Appends an item to the end of the list.
  632. Arguments:
  633. pvItem - Address of item to add to list.
  634. Returns: Nothing.
  635. Exceptions: OutOfMemory.
  636. Revision History:
  637. Date Description Programmer
  638. -------- --------------------------------------------------- ----------
  639. 06/24/96 Initial creation. BrianAu
  640. 09/06/96 Added exception handling. BrianAu
  641. */
  642. ///////////////////////////////////////////////////////////////////////////////
  643. VOID
  644. StructureList::Append(
  645. LPVOID pvItem
  646. )
  647. {
  648. DBGASSERT((NULL != pvItem));
  649. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  650. //
  651. // Yes, this is correct. We're "inserting" an item to append something
  652. // to the list. This saves a ( count - 1 ) calculation.
  653. //
  654. DBGASSERT((NULL != m_hdsa));
  655. Insert(pvItem, DSA_GetItemCount(m_hdsa));
  656. }
  657. ///////////////////////////////////////////////////////////////////////////////
  658. /* Function: StructureList::Remove
  659. Description: Removes an item from the list at a given index.
  660. Arguments:
  661. pvItem - Address of buffer to receive removed item. Assumes buffer
  662. is sized properly.
  663. index - List index where item is to be removed. All following
  664. items are shifted to one index lower.
  665. Returns:
  666. TRUE - Success.
  667. FALSE - Invalid index or container is empty.
  668. Revision History:
  669. Date Description Programmer
  670. -------- --------------------------------------------------- ----------
  671. 06/24/96 Initial creation. BrianAu
  672. */
  673. ///////////////////////////////////////////////////////////////////////////////
  674. BOOL
  675. StructureList::Remove(
  676. LPVOID pvItem,
  677. UINT index
  678. )
  679. {
  680. DBGASSERT((NULL != pvItem));
  681. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  682. DBGASSERT((NULL != m_hdsa));
  683. if (!DSA_GetItem(m_hdsa, index, pvItem) ||
  684. !DSA_DeleteItem(m_hdsa, index))
  685. {
  686. return FALSE;
  687. }
  688. return TRUE;
  689. }
  690. ///////////////////////////////////////////////////////////////////////////////
  691. /* Function: StructureList::Retrieve
  692. Description: Retrieve an item from the list at a given index.
  693. The item value is merely copied and not removed from the list.
  694. Arguments:
  695. pvItem - Address of buffer to receive removed item. Assumes buffer
  696. is sized properly.
  697. index - List index where item is to be retrieved.
  698. Returns:
  699. TRUE - Success.
  700. FALSE - Invalid index or empty container.
  701. Revision History:
  702. Date Description Programmer
  703. -------- --------------------------------------------------- ----------
  704. 06/24/96 Initial creation. BrianAu
  705. */
  706. ///////////////////////////////////////////////////////////////////////////////
  707. BOOL
  708. StructureList::Retrieve(
  709. LPVOID pvItem,
  710. UINT index
  711. )
  712. {
  713. DBGASSERT((NULL != pvItem));
  714. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  715. DBGASSERT((NULL != m_hdsa));
  716. if (!DSA_GetItem(m_hdsa, index, pvItem))
  717. {
  718. return FALSE;
  719. }
  720. return TRUE;
  721. }
  722. ///////////////////////////////////////////////////////////////////////////////
  723. /* Function: StructureList::RemoveLast
  724. Description: Removes the last item from the list.
  725. Arguments:
  726. pvItem - Address of buffer to receive removed item. Assumes buffer
  727. is sized properly.
  728. Returns:
  729. TRUE - Success.
  730. FALSE - Empty container.
  731. Revision History:
  732. Date Description Programmer
  733. -------- --------------------------------------------------- ----------
  734. 06/24/96 Initial creation. BrianAu
  735. */
  736. ///////////////////////////////////////////////////////////////////////////////
  737. BOOL
  738. StructureList::RemoveLast(
  739. LPVOID pvItem
  740. )
  741. {
  742. DBGASSERT((NULL != pvItem));
  743. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  744. DBGASSERT((NULL != m_hdsa));
  745. if (0 == DSA_GetItemCount(m_hdsa))
  746. return FALSE;
  747. Remove(pvItem, DSA_GetItemCount(m_hdsa) - 1);
  748. return TRUE;
  749. }
  750. ///////////////////////////////////////////////////////////////////////////////
  751. /* Function: StructureList::RetrieveLast
  752. Description: Retrieves the last pointer from the list.
  753. Arguments:
  754. pvItem - Address of buffer to receive removed item. Assumes buffer
  755. is sized properly.
  756. Returns:
  757. TRUE - Success.
  758. FALSE - Empty container.
  759. Revision History:
  760. Date Description Programmer
  761. -------- --------------------------------------------------- ----------
  762. 06/24/96 Initial creation. BrianAu
  763. */
  764. ///////////////////////////////////////////////////////////////////////////////
  765. BOOL
  766. StructureList::RetrieveLast(
  767. LPVOID pvItem
  768. )
  769. {
  770. DBGASSERT((NULL != pvItem));
  771. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  772. DBGASSERT((NULL != m_hdsa));
  773. if (0 == DSA_GetItemCount(m_hdsa))
  774. return FALSE;
  775. Retrieve(pvItem, DSA_GetItemCount(m_hdsa) - 1);
  776. return TRUE;
  777. }
  778. ///////////////////////////////////////////////////////////////////////////////
  779. /* Function: StructureList::Clear
  780. Description: Removes all items from the list.
  781. Arguments: None.
  782. Returns: Nothing.
  783. Revision History:
  784. Date Description Programmer
  785. -------- --------------------------------------------------- ----------
  786. 06/26/96 Initial creation. BrianAu
  787. */
  788. ///////////////////////////////////////////////////////////////////////////////
  789. VOID
  790. StructureList::Clear(
  791. VOID
  792. )
  793. {
  794. AutoLockCs lock(m_cs); // Get lock on container. Will auto-release.
  795. DBGASSERT((NULL != m_hdsa));
  796. DSA_DeleteAllItems(m_hdsa);
  797. }
  798. ///////////////////////////////////////////////////////////////////////////////
  799. /* Function: StructureListIterator::Advance
  800. Description: Both the Next() and Prev() iterator functions call this
  801. one function. It handles the actual iteration.
  802. Arguments:
  803. ppvOut - Address of pointer variable to receive the address of the
  804. item at the "current" iterator location. The iterator is
  805. advance (or retreated) after the pointer value is copied to the
  806. destination.
  807. bForward - TRUE = Advance toward end of list.
  808. FALSE = Advance toward front of list.
  809. Returns:
  810. NO_ERROR - Iterator advanced. Returned pointer is valid.
  811. E_FAIL - Iterator already at begining or end of list. Returned
  812. pointer will be NULL.
  813. Revision History:
  814. Date Description Programmer
  815. -------- --------------------------------------------------- ----------
  816. 06/24/96 Initial creation. BrianAu
  817. */
  818. ///////////////////////////////////////////////////////////////////////////////
  819. HRESULT
  820. StructureListIterator::Advance(
  821. LPVOID *ppvOut,
  822. BOOL bForward
  823. )
  824. {
  825. LPVOID pv = NULL;
  826. HRESULT hResult = NO_ERROR;
  827. DBGASSERT((NULL != ppvOut));
  828. m_pList->Lock();
  829. if (0 < m_pList->Count() && m_Index != EndOfList)
  830. {
  831. //
  832. // Get address of item at index "m_Index".
  833. //
  834. DBGASSERT((NULL != m_pList->m_hdsa));
  835. pv = DSA_GetItemPtr(m_pList->m_hdsa, m_Index);
  836. if (bForward)
  837. {
  838. //
  839. // Advance iterator index.
  840. //
  841. if ((UINT)(++m_Index) == m_pList->Count())
  842. m_Index = EndOfList;
  843. }
  844. else
  845. {
  846. //
  847. // Retreat iterator index.
  848. //
  849. m_Index--; // Will be -1 (EndOfList) if currently 0.
  850. }
  851. }
  852. else
  853. hResult = E_FAIL;
  854. m_pList->ReleaseLock();
  855. *ppvOut = pv; // Return pointer value.
  856. return hResult;
  857. }