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.

354 lines
8.3 KiB

  1. //=--------------------------------------------------------------------------=
  2. // StrColl.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implementation for our simple strings collections.
  13. //
  14. #include "IPServer.H"
  15. #include "SimpleEnumVar.H"
  16. #include "StringsColl.H"
  17. // for asserts
  18. //
  19. SZTHISFILE
  20. //=--------------------------------------------------------------------------=
  21. // CStringsCollection::CStringsCollection
  22. //=--------------------------------------------------------------------------=
  23. // constructor. sets up the safearray pointer.
  24. //
  25. // Parameters:
  26. // SAFEARRAY - [in] the collection we're working with.
  27. //
  28. // Notes:
  29. //
  30. CStringCollection::CStringCollection
  31. (
  32. SAFEARRAY *psa
  33. )
  34. : m_psa(psa)
  35. {
  36. ASSERT(m_psa, "Bogus Safearray pointer!");
  37. }
  38. //=--------------------------------------------------------------------------=
  39. // CStringCollection::~CStringCollection
  40. //=--------------------------------------------------------------------------=
  41. //
  42. // Notes:
  43. //
  44. CStringCollection::~CStringCollection()
  45. {
  46. }
  47. //=--------------------------------------------------------------------------=
  48. // CStringCollection::get_Count
  49. //=--------------------------------------------------------------------------=
  50. // returns the count of the things in the collection
  51. //
  52. // Parameters:
  53. // long * - [out] the count
  54. //
  55. // Output:
  56. // HRESULT - S_OK, one of the SAFEARRAY Scodes.
  57. //
  58. // Notes:
  59. // - we're assuming the safearray's lower bound is zero!
  60. //
  61. STDMETHODIMP CStringCollection::get_Count
  62. (
  63. long *plCount
  64. )
  65. {
  66. HRESULT hr;
  67. ASSERT(m_psa, "Who created a collection without a SAFEARRAY?");
  68. CHECK_POINTER(plCount);
  69. // get the bounds.
  70. //
  71. hr = SafeArrayGetUBound(m_psa, 1, plCount);
  72. CLEARERRORINFORET_ON_FAILURE(hr);
  73. // add one since we're zero-offset
  74. //
  75. (*plCount)++;
  76. return S_OK;
  77. }
  78. //=--------------------------------------------------------------------------=
  79. // CStringCollection::get_Item
  80. //=--------------------------------------------------------------------------=
  81. // returns a string given an INDEX
  82. //
  83. // Parameters:
  84. // long - [in] the index to get it from
  85. // BSTR * - [out] the item
  86. //
  87. // Output:
  88. // HRESULT - S_OK, E_OUTOFMEMORY
  89. //
  90. // Notes:
  91. //
  92. STDMETHODIMP CStringCollection::get_Item
  93. (
  94. long lIndex,
  95. BSTR *pbstrItem
  96. )
  97. {
  98. HRESULT hr;
  99. CHECK_POINTER(pbstrItem);
  100. // get the element from the safearray
  101. //
  102. hr = SafeArrayGetElement(m_psa, &lIndex, pbstrItem);
  103. CLEARERRORINFORET_ON_FAILURE(hr);
  104. // otherwise, we've got it, so we can return
  105. //
  106. return S_OK;
  107. }
  108. //=--------------------------------------------------------------------------=
  109. // CStringCollection::get__NewEnum
  110. //=--------------------------------------------------------------------------=
  111. // returns a new IEnumVARIANT object with the collection in it.
  112. //
  113. // Parameters:
  114. // IUnknown ** - [out] new enumvariant object.
  115. //
  116. // Output:
  117. // HRESULT - S_OK, E_OUTOFMEMORY
  118. //
  119. // Notes:
  120. //
  121. STDMETHODIMP CStringCollection::get__NewEnum
  122. (
  123. IUnknown **ppUnkNewEnum
  124. )
  125. {
  126. HRESULT hr;
  127. long l;
  128. CHECK_POINTER(ppUnkNewEnum);
  129. // get the count of things in the SAFEARRAY
  130. //
  131. hr = get_Count(&l);
  132. CLEARERRORINFORET_ON_FAILURE(hr);
  133. // create the object.
  134. //
  135. *ppUnkNewEnum = (IUnknown *) new CSimpleEnumVariant(m_psa, l);
  136. if (!*ppUnkNewEnum)
  137. CLEARERRORINFORET(E_OUTOFMEMORY);
  138. // refcount is already 1, so we can leave.
  139. //
  140. return S_OK;
  141. }
  142. //=--------------------------------------------------------------------------=
  143. //=--------------------------------------------------------------------------=
  144. // CStringDynaCollection::CStringDynaCollection
  145. //=--------------------------------------------------------------------------=
  146. // constructor for this object. doesn't do very much.
  147. //
  148. // Parameters:
  149. // same as for CStringCollection
  150. //
  151. // Notes:
  152. //
  153. CStringDynaCollection::CStringDynaCollection
  154. (
  155. SAFEARRAY *psa
  156. )
  157. : CStringCollection(psa)
  158. {
  159. }
  160. //=--------------------------------------------------------------------------=
  161. // CStringDynaCollection::~CStringDynaCollection
  162. //=--------------------------------------------------------------------------=
  163. // destructor.
  164. //
  165. // Notes:
  166. //
  167. CStringDynaCollection::~CStringDynaCollection()
  168. {
  169. }
  170. //=--------------------------------------------------------------------------=
  171. // CStringDynaCollection::put_Item
  172. //=--------------------------------------------------------------------------=
  173. // sets the value of an item in the array.
  174. //
  175. // Parameters:
  176. // long - [in] index at which to put it
  177. // BSTR - [in] new value.
  178. //
  179. // Output:
  180. // HRESULT - S_OK, safearray Scode.
  181. //
  182. // Notes:
  183. // - NULLs are converted to ""
  184. //
  185. STDMETHODIMP CStringDynaCollection::put_Item
  186. (
  187. long lIndex,
  188. BSTR bstr
  189. )
  190. {
  191. HRESULT hr;
  192. long l;
  193. BSTR bstr2 = NULL;
  194. // get the count and verify our index
  195. //
  196. hr = get_Count(&l);
  197. RETURN_ON_FAILURE(hr);
  198. if (lIndex < 0 || lIndex >= l)
  199. CLEARERRORINFORET(E_INVALIDARG);
  200. // put out the string, convert NULLs to ""
  201. //
  202. if (!bstr) {
  203. bstr2 = SysAllocString(L"");
  204. RETURN_ON_NULLALLOC(bstr2);
  205. }
  206. hr = SafeArrayPutElement(m_psa, &lIndex, (bstr) ? bstr : bstr2);
  207. if (bstr2) SysFreeString(bstr2);
  208. CLEARERRORINFORET_ON_FAILURE(hr);
  209. return S_OK;
  210. }
  211. //=--------------------------------------------------------------------------=
  212. // CStringDynaCollection::Add
  213. //=--------------------------------------------------------------------------=
  214. // adds a new string to the end of the collection.
  215. //
  216. // Parameters:
  217. // BSTR - [in] the new string to add
  218. //
  219. // Notes:
  220. //
  221. STDMETHODIMP CStringDynaCollection::Add
  222. (
  223. BSTR bstr
  224. )
  225. {
  226. SAFEARRAYBOUND sab;
  227. BSTR bstr2 = NULL;
  228. HRESULT hr;
  229. long l;
  230. // get the current size of the array.
  231. //
  232. hr = get_Count(&l);
  233. RETURN_ON_FAILURE(hr);
  234. // add one new elemnt
  235. //
  236. sab.cElements = l + 1;
  237. sab.lLbound = 0;
  238. // redim the array.
  239. //
  240. hr = SafeArrayRedim(m_psa, &sab);
  241. CLEARERRORINFORET_ON_FAILURE(hr);
  242. // put the out string, converting NULLs to ""
  243. //
  244. if (!bstr) {
  245. bstr2 = SysAllocString(L"");
  246. RETURN_ON_NULLALLOC(bstr2);
  247. }
  248. hr = SafeArrayPutElement(m_psa, &l, (bstr) ? bstr : bstr2);
  249. if (bstr2) SysFreeString(bstr2);
  250. CLEARERRORINFORET_ON_FAILURE(hr);
  251. return S_OK;
  252. }
  253. //=--------------------------------------------------------------------------=
  254. // CStringDynaCollection::Remove
  255. //=--------------------------------------------------------------------------=
  256. // removes an element from the collection, and shuffles all the rest down to
  257. // fill up the space.
  258. //
  259. // Parameters:
  260. // long - [in] index of dude to remove.
  261. //
  262. // Output:
  263. // HRESULT - S_OK, safearray Scodes.
  264. //
  265. // Notes:
  266. //
  267. STDMETHODIMP CStringDynaCollection::Remove
  268. (
  269. long lIndex
  270. )
  271. {
  272. SAFEARRAYBOUND sab;
  273. HRESULT hr;
  274. BSTR bstr;
  275. long lCount;
  276. long x, y;
  277. // first get the count of things in our array.
  278. //
  279. hr = get_Count(&lCount);
  280. RETURN_ON_FAILURE(hr);
  281. // check the index
  282. //
  283. if (lIndex < 0 || lIndex >= lCount)
  284. CLEARERRORINFORET(E_INVALIDARG);
  285. // let's go through, shuffling everything down one.
  286. //
  287. for (x = lIndex, y = x + 1; x < lCount - 1; x++, y++) {
  288. // get the next element.
  289. //
  290. hr = SafeArrayGetElement(m_psa, &y, &bstr);
  291. CLEARERRORINFORET_ON_FAILURE(hr);
  292. // set it at the current location
  293. //
  294. hr = SafeArrayPutElement(m_psa, &x, bstr);
  295. CLEARERRORINFORET_ON_FAILURE(hr);
  296. }
  297. // we're at the last element. let's go and kill it.
  298. //
  299. sab.cElements = lCount - 1;
  300. sab.lLbound = 0;
  301. // CONSIDER: 9.95 -- there is a bug in oleaut32.dll which causes the
  302. // below to fail if cElements = 0.
  303. //
  304. hr = SafeArrayRedim(m_psa, &sab);
  305. CLEARERRORINFORET_ON_FAILURE(hr);
  306. // we're done. go bye-bye.
  307. //
  308. return S_OK;
  309. }
  310.