Source code of Windows XP (NT5)
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.

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