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.

394 lines
9.8 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: enumstr.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 3-19-97 srikants Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <pch.cxx>
  18. #pragma hdrstop
  19. #include <enumstr.hxx>
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Member: CEnumString::QueryInterface
  23. //
  24. // Synopsis:
  25. //
  26. // Arguments: [riid] -
  27. // [ppvObject] -
  28. //
  29. // Returns:
  30. //
  31. // History: 11-27-96 srikants Created
  32. //
  33. //----------------------------------------------------------------------------
  34. STDMETHODIMP CEnumString::QueryInterface(
  35. REFIID riid,
  36. void **ppvObject)
  37. {
  38. Win4Assert( 0 != ppvObject );
  39. if ( IID_IEnumString == riid )
  40. *ppvObject = (void *)((IEnumString *)this);
  41. else if ( IID_IUnknown == riid )
  42. *ppvObject = (void *)((IUnknown *)this);
  43. else
  44. {
  45. *ppvObject = 0;
  46. return E_NOINTERFACE;
  47. }
  48. AddRef();
  49. return S_OK;
  50. } //QueryInterface
  51. //+---------------------------------------------------------------------------
  52. //
  53. // Member: CEnumString::AddRef
  54. //
  55. // History: 11-22-96 srikants Created
  56. //
  57. //----------------------------------------------------------------------------
  58. STDMETHODIMP_(ULONG) CEnumString::AddRef()
  59. {
  60. return InterlockedIncrement(&_refCount);
  61. } //AddRef
  62. //+---------------------------------------------------------------------------
  63. //
  64. // Member: CEnumString::Release
  65. //
  66. // History: 11-22-96 srikants Created
  67. //
  68. //----------------------------------------------------------------------------
  69. STDMETHODIMP_(ULONG) CEnumString::Release()
  70. {
  71. Win4Assert( _refCount > 0 );
  72. LONG refCount = InterlockedDecrement(&_refCount);
  73. if ( refCount <= 0 )
  74. delete this;
  75. return (ULONG) refCount;
  76. } //Release
  77. //+---------------------------------------------------------------------------
  78. //
  79. // Member: CEnumString::Clone
  80. //
  81. // Synopsis: Makes a copy of this object.
  82. //
  83. // Arguments: [ppEnumStr] - If successful, will have the refcounted pointer
  84. // to IEnumString interface.
  85. //
  86. // Returns: S_OK if successful; Failure code otherwise.
  87. //
  88. // History: 3-21-97 srikants Created
  89. //
  90. //----------------------------------------------------------------------------
  91. STDMETHODIMP CEnumString::Clone( IEnumString ** ppEnumStr )
  92. {
  93. SCODE sc = S_OK;
  94. TRY
  95. {
  96. CEnumString * pCopy = new CEnumString( _aStr.Size() );
  97. for ( unsigned i = 0; i < _cValid; i++ )
  98. pCopy->Append( _aStr[i] );
  99. *ppEnumStr = pCopy;
  100. }
  101. CATCH( CException, e )
  102. {
  103. sc = e.GetErrorCode();
  104. ciDebugOut(( DEB_ERROR, "CEnumString::Clone failed. Error (0x%X)\n", sc ));
  105. }
  106. END_CATCH
  107. return sc;
  108. }
  109. //+---------------------------------------------------------------------------
  110. //
  111. // Member: CEnumString::Next
  112. //
  113. // Synopsis: Retrieves the specified number of strings. If there are
  114. // fewer strings than requested, then the returned number is
  115. // indicated in the pceltFetched parameter.
  116. //
  117. // Arguments: [celt] -
  118. // [rgelt] -
  119. // [pceltFetched] -
  120. //
  121. // Returns: S_OK if fetched celt.
  122. // S_FALSE otherwise.
  123. //
  124. // History: 3-19-97 srikants Created
  125. //
  126. // Notes: No copies are being made, but pointers to internal data.
  127. // Also, this is not OLE memory but if it is read-only memory,
  128. // it doesn't matter.
  129. //
  130. //----------------------------------------------------------------------------
  131. STDMETHODIMP CEnumString::Next( ULONG celt,
  132. LPOLESTR * rgelt,
  133. ULONG * pceltFetched )
  134. {
  135. Win4Assert( _iCurrEnum <= _cValid );
  136. *pceltFetched = 0;
  137. while ( (_iCurrEnum < _cValid) && ( (*pceltFetched) < celt ) )
  138. {
  139. rgelt[(*pceltFetched)++] = _aStr.Get(_iCurrEnum++);
  140. }
  141. ULONG cAdded = *pceltFetched;
  142. while ( cAdded < celt )
  143. rgelt[cAdded++] = 0; // Must fill the remaining with NULLs.
  144. return *pceltFetched == celt ? S_OK : S_FALSE;
  145. }
  146. //+---------------------------------------------------------------------------
  147. //
  148. // Member: CEnumString::Skip
  149. //
  150. // Synopsis: Skips the requested number of elements.
  151. //
  152. // Arguments: [celt] - Number of elements to skip.
  153. //
  154. // Returns: S_OK if skipped the specified number; S_FALSE o/w
  155. //
  156. // History: 3-19-97 srikants Created
  157. //
  158. // Notes: If we cannot skip as many as requested, we don't skip any.
  159. //
  160. //----------------------------------------------------------------------------
  161. STDMETHODIMP CEnumString::Skip( ULONG celt )
  162. {
  163. Win4Assert( _iCurrEnum <= _cValid );
  164. if ( _iCurrEnum + celt <= _cValid )
  165. {
  166. _iCurrEnum += celt;
  167. return S_OK;
  168. }
  169. else
  170. {
  171. return S_FALSE;
  172. }
  173. }
  174. //+---------------------------------------------------------------------------
  175. //
  176. // Member: CEnumString::Append
  177. //
  178. // Synopsis: Appends the given string to the collection.
  179. //
  180. // Arguments: [pwszString] -
  181. //
  182. // History: 3-19-97 srikants Created
  183. //
  184. //----------------------------------------------------------------------------
  185. void CEnumString::Append( WCHAR const * pwszString )
  186. {
  187. Win4Assert( 0 != pwszString );
  188. unsigned cwc = wcslen( pwszString ) + 1;
  189. XArray<WCHAR> xwszCopy( cwc );
  190. RtlCopyMemory( xwszCopy.GetPointer(), pwszString, cwc * sizeof WCHAR );
  191. _aStr.Add( xwszCopy.GetPointer(), _cValid );
  192. xwszCopy.Acquire();
  193. _cValid++;
  194. }
  195. //+---------------------------------------------------------------------------
  196. //
  197. // Member: CEnumWorkid::QueryInterface
  198. //
  199. // History: 11-27-96 srikants Created
  200. //
  201. //----------------------------------------------------------------------------
  202. STDMETHODIMP CEnumWorkid::QueryInterface(
  203. REFIID riid,
  204. void **ppvObject)
  205. {
  206. Win4Assert( 0 != ppvObject );
  207. if ( RtlEqualMemory( &riid, &IID_IUnknown, sizeof(REFIID)) )
  208. {
  209. AddRef();
  210. *ppvObject = (void *)((IUnknown *)this);
  211. return S_OK;
  212. }
  213. else if ( RtlEqualMemory( &riid, &IID_ICiEnumWorkids, sizeof(REFIID)) )
  214. {
  215. AddRef();
  216. *ppvObject = (void *)((ICiEnumWorkids *)this);
  217. return S_OK;
  218. }
  219. else
  220. {
  221. *ppvObject = 0;
  222. return E_NOINTERFACE;
  223. }
  224. } //QueryInterface
  225. //+---------------------------------------------------------------------------
  226. //
  227. // Member: CEnumWorkid::AddRef
  228. //
  229. // History: 11-22-96 srikants Created
  230. //
  231. //----------------------------------------------------------------------------
  232. STDMETHODIMP_(ULONG) CEnumWorkid::AddRef()
  233. {
  234. InterlockedIncrement(&_refCount);
  235. return (ULONG) _refCount;
  236. } //AddRef
  237. //+---------------------------------------------------------------------------
  238. //
  239. // Member: CEnumWorkid::Release
  240. //
  241. // History: 11-22-96 srikants Created
  242. //
  243. //----------------------------------------------------------------------------
  244. STDMETHODIMP_(ULONG) CEnumWorkid::Release()
  245. {
  246. Win4Assert( _refCount > 0 );
  247. LONG refCount = InterlockedDecrement(&_refCount);
  248. if ( refCount <= 0 )
  249. delete this;
  250. return (ULONG) refCount;
  251. } //Release
  252. //+---------------------------------------------------------------------------
  253. //
  254. // Member: CEnumWorkid::Next
  255. //
  256. // Synopsis: Retrieves the specified number of workids. If there are
  257. // fewer workids than requested, then the returned number is
  258. // indicated in the pceltFetched parameter.
  259. //
  260. // Arguments: [celt] - Number of elements requested
  261. // [rgelt] - Array to fill the workids in
  262. // [pceltFetched] - Number fetched.
  263. //
  264. // Returns: S_OK if fetched celt.
  265. // S_FALSE otherwise.
  266. //
  267. // History: 3-19-97 srikants Created
  268. //
  269. //----------------------------------------------------------------------------
  270. STDMETHODIMP CEnumWorkid::Next( ULONG celt,
  271. WORKID * rgelt,
  272. ULONG * pceltFetched )
  273. {
  274. Win4Assert( _iCurrEnum <= _cValid );
  275. *pceltFetched = 0;
  276. while ( (_iCurrEnum < _cValid) && ( (*pceltFetched) < celt ) )
  277. {
  278. rgelt[(*pceltFetched)++] = _aWorkids.Get(_iCurrEnum++);
  279. }
  280. ULONG cAdded = *pceltFetched;
  281. while ( cAdded < celt )
  282. rgelt[cAdded++] = 0; // Must fill the remaining with NULLs.
  283. return *pceltFetched == celt ? S_OK : S_FALSE;
  284. }
  285. //+---------------------------------------------------------------------------
  286. //
  287. // Member: CEnumWorkid::Skip
  288. //
  289. // Synopsis: Skips the requested number of elements.
  290. //
  291. // Arguments: [celt] - Number of elements to skip.
  292. //
  293. // Returns: S_OK if skipped the specified number; S_FALSE o/w
  294. //
  295. // History: 3-19-97 srikants Created
  296. //
  297. // Notes: If we cannot skip as many as requested, we don't skip any.
  298. //
  299. //----------------------------------------------------------------------------
  300. STDMETHODIMP CEnumWorkid::Skip( ULONG celt )
  301. {
  302. Win4Assert( _iCurrEnum <= _cValid );
  303. if ( _iCurrEnum + celt <= _cValid )
  304. {
  305. _iCurrEnum += celt;
  306. return S_OK;
  307. }
  308. else
  309. {
  310. return S_FALSE;
  311. }
  312. }
  313. //+---------------------------------------------------------------------------
  314. //
  315. // Member: CEnumWorkid::Append
  316. //
  317. // Synopsis: Appends the given string to the collection.
  318. //
  319. // Arguments: [wid] - Appends the given workid to the collection.
  320. //
  321. // History: 3-19-97 srikants Created
  322. //
  323. //----------------------------------------------------------------------------
  324. void CEnumWorkid::Append( WORKID wid )
  325. {
  326. _aWorkids.Add( wid, _cValid );
  327. _cValid++;
  328. }