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.

660 lines
15 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: ary.cxx
  4. //
  5. // Module: CMDIAL32.DLL
  6. //
  7. // Synopsis: Generic dynamic array class -- CFormsAry
  8. //
  9. // Copyright (c) 1992-1998 Microsoft Corporation
  10. //
  11. // Author: quintinb Created Header 8/17/99
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "cmmaster.h"
  15. #include "cm_misc.h"
  16. #include "ary.hxx"
  17. #define CFORMSARY_MAXELEMSIZE 128
  18. // CFormsAry class
  19. //
  20. //
  21. //+------------------------------------------------------------------------
  22. //
  23. // Member: CFormsAry::~CFormsAry
  24. //
  25. // Synopsis: Resizeable array destructor. Frees storage allocated for the
  26. // array.
  27. //
  28. //-------------------------------------------------------------------------
  29. CFormsAry::~CFormsAry( )
  30. {
  31. MemFree(PData());
  32. }
  33. //+------------------------------------------------------------------------
  34. //
  35. // Member: CFormsAry::EnsureSize
  36. //
  37. // Synopsis: Ensures that the array is at least the given size. That is,
  38. // if EnsureSize(c) succeeds, then (c-1) is a valid index. Note
  39. // that the array maintains a separate count of the number of
  40. // elements logically in the array, which is obtained with the
  41. // Size/SetSize methods. The logical size of the array is never
  42. // larger than the allocated size of the array.
  43. //
  44. // Arguments: cb Element size
  45. // c New allocated size for the array.
  46. //
  47. // Returns: HRESULT
  48. //
  49. //-------------------------------------------------------------------------
  50. HRESULT
  51. CFormsAry::EnsureSize(size_t cb, int c)
  52. {
  53. HRESULT hr;
  54. unsigned cbAlloc = ((c + 7) & ~7) * cb;
  55. MYDBGASSERT(c >= 0);
  56. if (c > ((_c + 7) & ~7) && cbAlloc > MemGetSize(PData()))
  57. {
  58. hr = MemRealloc((void **)&PData(), cbAlloc);
  59. }
  60. else
  61. {
  62. hr = S_OK;
  63. }
  64. return hr;
  65. }
  66. //+------------------------------------------------------------------------
  67. //
  68. // Member: CFormsAry::AppendIndirect
  69. //
  70. // Synopsis: Appends the given element to the end of the array, incrementing
  71. // the array's logical size, and growing the array's allocated
  72. // size if necessary. Note that the element is passed with a
  73. // pointer, rather than directly.
  74. //
  75. // Arguments: cb Element size
  76. // pv Pointer to the element to be appended
  77. //
  78. // Returns: HRESULT
  79. //
  80. //-------------------------------------------------------------------------
  81. HRESULT
  82. CFormsAry::AppendIndirect(size_t cb, void * pv)
  83. {
  84. HRESULT hr;
  85. hr = EnsureSize(cb, _c + 1);
  86. if (hr)
  87. return hr;
  88. memcpy(Deref(cb, _c), pv, cb);
  89. _c++;
  90. return NOERROR;
  91. }
  92. #if 0
  93. /*
  94. //+------------------------------------------------------------------------
  95. //
  96. // Member: CFormsAry::Delete
  97. //
  98. // Synopsis: Removes the i'th element of the array, shuffling all
  99. // elements that follow one slot towards the beginning of the
  100. // array.
  101. //
  102. // Arguments: cb Element size
  103. // i Element to delete
  104. //
  105. //-------------------------------------------------------------------------
  106. void
  107. CFormsAry::Delete(size_t cb, int i)
  108. {
  109. MYDBGASSERT(i >= 0);
  110. MYDBGASSERT(i < _c);
  111. memmove(((BYTE *) PData()) + (i * cb),
  112. ((BYTE *) PData()) + ((i + 1) * cb),
  113. (_c - i - 1) * cb);
  114. _c--;
  115. }
  116. //+------------------------------------------------------------------------
  117. //
  118. // Member: CFormsAry::DeleteByValueIndirect
  119. //
  120. // Synopsis: Removes the element matching the given value.
  121. //
  122. // Arguments: cb Element size
  123. // pv Element to delete
  124. //
  125. // Returuns: True if found & deleted.
  126. //
  127. //-------------------------------------------------------------------------
  128. BOOL
  129. CFormsAry::DeleteByValueIndirect(size_t cb, void *pv)
  130. {
  131. int i = FindIndirect(cb, pv);
  132. if (i >= 0)
  133. {
  134. Delete(cb, i);
  135. return TRUE;
  136. }
  137. else
  138. {
  139. return FALSE;
  140. }
  141. }
  142. //+------------------------------------------------------------------------
  143. //
  144. // Member: CFormsAry::DeleteMultiple
  145. //
  146. // Synopsis: Removes a range of elements of the array, shuffling all
  147. // elements that follow the last element being deleted slot
  148. // towards the beginning of the array.
  149. //
  150. // Arguments: cb Element size
  151. // start First element to delete
  152. // end Last element to delete
  153. //
  154. //-------------------------------------------------------------------------
  155. void
  156. CFormsAry::DeleteMultiple(size_t cb, int start, int end)
  157. {
  158. MYDBGASSERT((start >= 0) && (end >= 0));
  159. MYDBGASSERT((start < _c) && (end < _c));
  160. MYDBGASSERT(end >= start);
  161. if (end < (_c - 1))
  162. {
  163. memmove(((BYTE *) PData()) + (start * cb),
  164. ((BYTE *) PData()) + ((end + 1) * cb),
  165. (_c - end - 1) * cb);
  166. }
  167. _c -= (end - start) + 1;
  168. }
  169. //+------------------------------------------------------------------------
  170. //
  171. // Member: CFormsAry::DeleteAll
  172. //
  173. // Synopsis: Efficient method for emptying array of any contents
  174. //
  175. //-------------------------------------------------------------------------
  176. void
  177. CFormsAry::DeleteAll(void)
  178. {
  179. MemFree(PData());
  180. PData() = NULL;
  181. _c = 0;
  182. }
  183. //+------------------------------------------------------------------------
  184. //
  185. // Member: CFormsAry::InsertIndirect
  186. //
  187. // Synopsis: Inserts a pointer pv at index i. The element previously at
  188. // index i, and all elements that follow it, are shuffled one
  189. // slot away towards the end of the array.Note that the
  190. // clement is passed with a pointer, rather than directly.
  191. //
  192. // Arguments: cb Element size
  193. // i Index to insert...
  194. // pv ...this pointer at
  195. //
  196. //-------------------------------------------------------------------------
  197. HRESULT
  198. CFormsAry::InsertIndirect(size_t cb, int i, void *pv)
  199. {
  200. HRESULT hr;
  201. hr = EnsureSize(cb, _c + 1);
  202. if (hr)
  203. return hr;
  204. memmove(((BYTE *) PData()) + ((i + 1) * cb),
  205. ((BYTE *) PData()) + (i * cb),
  206. (_c - i ) * cb);
  207. memcpy(Deref(cb, i), pv, cb);
  208. _c++;
  209. return NOERROR;
  210. }
  211. //+------------------------------------------------------------------------
  212. //
  213. // Member: CFormsAry::BringToFront
  214. //
  215. // Synopsis: Moves the i'th element to the front of the array, shuffling
  216. // intervening elements to make room.
  217. //
  218. // Arguments: i
  219. //
  220. //-------------------------------------------------------------------------
  221. void
  222. CFormsAry::BringToFront(size_t cb, int i)
  223. {
  224. BYTE rgb[CFORMSARY_MAXELEMSIZE];
  225. MYDBGASSERT(cb <= CFORMSARY_MAXELEMSIZE);
  226. memcpy(rgb, ((BYTE *) PData()) + (i * cb), cb);
  227. memmove(((BYTE *) PData()) + cb, PData(), i * cb);
  228. memcpy(PData(), rgb, cb);
  229. }
  230. //+------------------------------------------------------------------------
  231. //
  232. // Member: CFormsAry::SendToBack
  233. //
  234. // Synopsis: Moves the i'th element to the back of the array (that is,
  235. // the largest index less than the logical size.) Any intervening
  236. // elements are shuffled out of the way.
  237. //
  238. // Arguments: i
  239. //
  240. //-------------------------------------------------------------------------
  241. void
  242. CFormsAry::SendToBack(size_t cb, int i)
  243. {
  244. BYTE rgb[CFORMSARY_MAXELEMSIZE];
  245. MYDBGASSERT(cb <= CFORMSARY_MAXELEMSIZE);
  246. memcpy(rgb, ((BYTE *) PData()) + (i * cb), cb);
  247. memmove(((BYTE *) PData()) + (i * cb),
  248. ((BYTE *) PData()) + ((i + 1) * cb),
  249. (_c - i - 1) * cb);
  250. memcpy(((BYTE *) PData()) + ((_c - 1) * cb), rgb, cb);
  251. }
  252. //+---------------------------------------------------------------------------
  253. //
  254. // Member: CFormsAry::Swap
  255. //
  256. // Synopsis: swap two members of array with each other.
  257. //
  258. // Arguments: cb size of elements
  259. // i1 1st element
  260. // i2 2nd element
  261. //----------------------------------------------------------------------------
  262. void
  263. CFormsAry::Swap(size_t cb, int i1, int i2)
  264. {
  265. BYTE rgb[CFORMSARY_MAXELEMSIZE];
  266. MYDBGASSERT(cb <= CFORMSARY_MAXELEMSIZE);
  267. if (i1 >= _c)
  268. i1 = _c - 1;
  269. if (i2 >= _c)
  270. i2 = _c - 1;
  271. if (i1 != i2)
  272. {
  273. memcpy(rgb, ((BYTE *) PData()) + (i1 * cb), cb);
  274. memcpy(((BYTE *) PData()) + (i1 * cb), ((BYTE *) PData()) + (i2 * cb), cb);
  275. memcpy(((BYTE *) PData()) + (i2 * cb), rgb, cb);
  276. }
  277. }
  278. //+---------------------------------------------------------------------------
  279. //
  280. // Member: CFormsAry::FindIndirect
  281. //
  282. // Synopsis: Finds an element of a non-pointer array.
  283. //
  284. // Arguments: cb The size of the element.
  285. // pv Pointer to the element.
  286. //
  287. // Returns: The index of the element if found, otherwise -1.
  288. //
  289. //----------------------------------------------------------------------------
  290. int
  291. CFormsAry::FindIndirect(size_t cb, void * pv)
  292. {
  293. int i;
  294. void * pvT;
  295. pvT = PData();
  296. for (i = _c; i > 0; i--)
  297. {
  298. if (!memcmp(pv, pvT, cb))
  299. return _c - i;
  300. pvT = (char *) pvT + cb;
  301. }
  302. return -1;
  303. }
  304. //+---------------------------------------------------------------------------
  305. //
  306. // Member: CFormsAry::CopyAppend
  307. //
  308. // Synopsis: Copies the entire contents of another CFormsAry object and
  309. // appends it to the end of the array.
  310. //
  311. // Arguments: ary Object to copy.
  312. // fAddRef Addref the elements on copy?
  313. //
  314. //----------------------------------------------------------------------------
  315. HRESULT
  316. CFormsAry::CopyAppend(size_t cb, const CFormsAry& ary, BOOL fAddRef)
  317. {
  318. return (CopyAppendIndirect(cb, ary._c, ((CFormsAry *)&ary)->PData(), fAddRef));
  319. }
  320. HRESULT
  321. CFormsAry::CopyAppendIndirect(size_t cb, int c, void * pv, BOOL fAddRef)
  322. {
  323. IUnknown ** ppUnk; // elem to addref
  324. if (EnsureSize(cb, _c + c))
  325. return E_OUTOFMEMORY;
  326. if (pv)
  327. {
  328. memcpy((BYTE*) PData() + (_c * cb), pv, c * cb);
  329. }
  330. _c += c;
  331. if (fAddRef)
  332. {
  333. for (ppUnk = (IUnknown **) pv; c > 0; c--, ppUnk++)
  334. {
  335. (*ppUnk)->AddRef();
  336. }
  337. }
  338. return S_OK;
  339. }
  340. //+---------------------------------------------------------------------------
  341. //
  342. // Member: CFormsAry::Copy
  343. //
  344. // Synopsis: Creates a copy from another CFormsAry object.
  345. //
  346. // Arguments: ary Object to copy.
  347. // fAddRef Addref the elements on copy?
  348. //
  349. //----------------------------------------------------------------------------
  350. HRESULT
  351. CFormsAry::Copy(size_t cb, const CFormsAry& ary, BOOL fAddRef)
  352. {
  353. return (CopyIndirect(cb, ary._c, ((CFormsAry *)&ary)->PData(), fAddRef));
  354. }
  355. //+------------------------------------------------------------------------
  356. //
  357. // Member: CFormsAry::CopyIndirect
  358. //
  359. // Synopsis: Fills a forms array from a C-style array of raw data
  360. //
  361. // Arguments: [cb]
  362. // [c]
  363. // [pv]
  364. // [fAddRef]
  365. //
  366. // Returns: HRESULT
  367. //
  368. //-------------------------------------------------------------------------
  369. HRESULT
  370. CFormsAry::CopyIndirect(size_t cb, int c, void * pv, BOOL fAddRef)
  371. {
  372. size_t cbArray;
  373. IUnknown ** ppUnk;
  374. if (pv == PData())
  375. return S_OK;
  376. DeleteAll();
  377. if (pv)
  378. {
  379. cbArray = c * cb;
  380. PData() = MemAlloc(cbArray);
  381. if (!PData())
  382. return E_OUTOFMEMORY;
  383. memcpy(PData(), pv, cbArray);
  384. }
  385. _c = c;
  386. if (fAddRef)
  387. {
  388. for (ppUnk = (IUnknown **) PData(); c > 0; c--, ppUnk++)
  389. {
  390. (*ppUnk)->AddRef();
  391. }
  392. }
  393. return S_OK;
  394. }
  395. HRESULT
  396. CFormsPtrAry::ClearAndReset()
  397. {
  398. // why does this function reallocate memory, rather than
  399. // just memset'ing to 0? (chrisz)
  400. PData() = NULL;
  401. HRESULT hr = EnsureSize(_c);
  402. _c = 0;
  403. return hr;
  404. }
  405. //+------------------------------------------------------------------------
  406. //
  407. // Member: CFormsPtrAry::*
  408. //
  409. // Synopsis: CFormsPtrAry elements are always of size four.
  410. // The following functions encode this knowledge.
  411. //
  412. //-------------------------------------------------------------------------
  413. HRESULT
  414. CFormsPtrAry::EnsureSize(int c)
  415. {
  416. return CFormsAry::EnsureSize(sizeof(void *), c);
  417. }
  418. HRESULT
  419. CFormsPtrAry::Append(void * pv)
  420. {
  421. return CFormsAry::AppendIndirect(sizeof(void *), &pv);
  422. }
  423. HRESULT
  424. CFormsPtrAry::Insert(int i, void * pv)
  425. {
  426. return CFormsAry::InsertIndirect(sizeof(void *), i, &pv);
  427. }
  428. int
  429. CFormsPtrAry::Find(void * pv)
  430. {
  431. int i;
  432. void ** ppv;
  433. for (i = 0, ppv = (void **) PData(); i < _c; i++, ppv++)
  434. {
  435. if (pv == *ppv)
  436. return i;
  437. }
  438. return -1;
  439. }
  440. void
  441. CFormsPtrAry::Delete(int i)
  442. {
  443. CFormsAry::Delete(sizeof(void *), i);
  444. }
  445. BOOL
  446. CFormsPtrAry::DeleteByValue(void *pv)
  447. {
  448. int i = Find(pv);
  449. if (i >= 0)
  450. {
  451. CFormsAry::Delete(sizeof(void *), i);
  452. return TRUE;
  453. }
  454. else
  455. {
  456. return FALSE;
  457. }
  458. }
  459. void
  460. CFormsPtrAry::DeleteMultiple(int start, int end)
  461. {
  462. CFormsAry::DeleteMultiple(sizeof(void*), start, end);
  463. }
  464. void
  465. CFormsPtrAry::ReleaseAndDelete(int idx)
  466. {
  467. IUnknown * pUnk;
  468. MYDBGASSERT(idx <= _c);
  469. // grab element at idx
  470. pUnk = ((IUnknown **) PData())[idx];
  471. if (pUnk)
  472. (pUnk)->Release();
  473. Delete(idx);
  474. }
  475. void
  476. CFormsPtrAry::ReleaseAll(void)
  477. {
  478. int i;
  479. IUnknown ** ppUnk;
  480. for (i = 0, ppUnk = (IUnknown **) PData(); i < _c; i++, ppUnk++)
  481. {
  482. if (*ppUnk)
  483. (*ppUnk)->Release();
  484. }
  485. DeleteAll();
  486. }
  487. void
  488. CFormsPtrAry::BringToFront(int i)
  489. {
  490. CFormsAry::BringToFront(sizeof(void *), i);
  491. }
  492. void
  493. CFormsPtrAry::SendToBack(int i)
  494. {
  495. CFormsAry::SendToBack(sizeof(void *), i);
  496. }
  497. void
  498. CFormsPtrAry::Swap(int i1, int i2)
  499. {
  500. CFormsAry::Swap(sizeof(void *), i1, i2);
  501. }
  502. HRESULT
  503. CFormsPtrAry::CopyAppendIndirect(int c, void * pv, BOOL fAddRef)
  504. {
  505. return CFormsAry::CopyAppendIndirect(sizeof(void *), c, pv, fAddRef);
  506. }
  507. HRESULT
  508. CFormsPtrAry::CopyAppend(const CFormsAry& ary, BOOL fAddRef)
  509. {
  510. return CFormsAry::CopyAppend(sizeof(void *), ary, fAddRef);
  511. }
  512. HRESULT
  513. CFormsPtrAry::CopyIndirect(int c, void * pv, BOOL fAddRef)
  514. {
  515. return CFormsAry::CopyIndirect(sizeof(void *), c, pv, fAddRef);
  516. }
  517. HRESULT
  518. CFormsPtrAry::Copy(const CFormsAry& ary, BOOL fAddRef)
  519. {
  520. return CFormsAry::Copy(sizeof(void *), ary, fAddRef);
  521. }
  522. HRESULT
  523. CFormsPtrAry::EnumElements(
  524. REFIID iid,
  525. void ** ppv,
  526. BOOL fAddRef,
  527. BOOL fCopy,
  528. BOOL fDelete)
  529. {
  530. return CFormsAry::EnumElements(
  531. sizeof(void *),
  532. iid,
  533. ppv,
  534. fAddRef,
  535. fCopy,
  536. fDelete);
  537. }
  538. HRESULT
  539. CFormsPtrAry::EnumVARIANT(
  540. VARTYPE vt,
  541. IEnumVARIANT ** ppenum,
  542. BOOL fCopy,
  543. BOOL fDelete)
  544. {
  545. return CFormsAry::EnumVARIANT(
  546. sizeof(void *),
  547. vt,
  548. ppenum,
  549. fCopy,
  550. fDelete);
  551. }
  552. */
  553. #endif