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.

413 lines
10 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. QueryResultCollection.cpp
  5. Abstract:
  6. This file contains the implementation of the CPCHQueryResultCollection class,
  7. which is used to store results of queries.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 07/26/99
  10. created
  11. ******************************************************************************/
  12. #include "stdafx.h"
  13. ////////////////////////////////////////////////////////////////////////////////
  14. static const DWORD l_dwVersion = 0x02425251; // QRC 02
  15. ////////////////////////////////////////////////////////////////////////////////
  16. struct ElementHolder
  17. {
  18. CPCHQueryResult* obj;
  19. long pos;
  20. };
  21. class ElementSorter
  22. {
  23. CPCHQueryResultCollection::SortMode m_mode;
  24. public:
  25. ElementSorter( /*[in]*/ CPCHQueryResultCollection::SortMode mode ) : m_mode(mode) {}
  26. bool operator()( ElementHolder& left, ElementHolder& right )
  27. {
  28. const CPCHQueryResult::Payload& leftData = left .obj->GetData();
  29. const CPCHQueryResult::Payload& rightData = right.obj->GetData();
  30. int iCmp = 0;
  31. //
  32. // Priority is sorted from highest to lowest, so negate iCmp;
  33. //
  34. switch(m_mode)
  35. {
  36. case CPCHQueryResultCollection::SORT_BYCONTENTTYPE: iCmp = ( leftData.m_lType - rightData.m_lType ); break;
  37. case CPCHQueryResultCollection::SORT_BYPRIORITY : iCmp = -( leftData.m_lPriority - rightData.m_lPriority ); break;
  38. case CPCHQueryResultCollection::SORT_BYURL : iCmp = MPC::StrICmp( leftData.m_bstrTopicURL, rightData.m_bstrTopicURL ); break;
  39. case CPCHQueryResultCollection::SORT_BYTITLE : iCmp = MPC::StrICmp( leftData.m_bstrTitle , rightData.m_bstrTitle ); break;
  40. }
  41. if(iCmp < 0) return true;
  42. if(iCmp > 0) return false;
  43. return (left.pos < right.pos);
  44. }
  45. };
  46. ////////////////////////////////////////////////////////////////////////////////
  47. CPCHQueryResultCollection::CPCHQueryResultCollection()
  48. {
  49. // List m_results;
  50. }
  51. CPCHQueryResultCollection::~CPCHQueryResultCollection()
  52. {
  53. Erase();
  54. }
  55. ////////////////////////////////////////
  56. HRESULT CPCHQueryResultCollection::MakeLocalCopyIfPossible( /*[in]*/ IPCHCollection* pRemote ,
  57. /*[out]*/ IPCHCollection* *pLocal )
  58. {
  59. __HCP_FUNC_ENTRY( "CPCHQueryResultCollection::MakeLocalCopyIfPossible" );
  60. HRESULT hr;
  61. CComPtr<CPCHQueryResultCollection> pColl;
  62. CComPtr<IPersistStream> persistRemote;
  63. CComPtr<IPersistStream> persistLocal;
  64. CComPtr<IStream> stream;
  65. MPC::Serializer_IStream ser;
  66. __MPC_PARAMCHECK_BEGIN(hr)
  67. __MPC_PARAMCHECK_NOTNULL(pRemote);
  68. __MPC_PARAMCHECK_POINTER_AND_SET(pLocal,NULL);
  69. __MPC_PARAMCHECK_END();
  70. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pColl ));
  71. __MPC_EXIT_IF_METHOD_FAILS(hr, pRemote->QueryInterface( IID_IPersistStream, (void**)&persistRemote ));
  72. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl ->QueryInterface( IID_IPersistStream, (void**)&persistLocal ));
  73. __MPC_EXIT_IF_METHOD_FAILS(hr, ser.GetStream ( &stream ));
  74. //
  75. // Convert from stream to live object.
  76. //
  77. __MPC_EXIT_IF_METHOD_FAILS(hr, persistRemote->Save( stream, FALSE ));
  78. __MPC_EXIT_IF_METHOD_FAILS(hr, ser.Reset ( )); // Rewind stream.
  79. __MPC_EXIT_IF_METHOD_FAILS(hr, persistLocal ->Load( stream ));
  80. *pLocal = pColl.Detach();
  81. hr = S_OK;
  82. __HCP_FUNC_CLEANUP;
  83. //
  84. // In case of failure, use the remote copy...
  85. //
  86. if(FAILED(hr) && pRemote && pLocal)
  87. {
  88. (*pLocal = pRemote)->AddRef();
  89. }
  90. __HCP_FUNC_EXIT(hr);
  91. }
  92. ////////////////////////////////////////
  93. STDMETHODIMP CPCHQueryResultCollection::GetClassID( /*[out]*/ CLSID *pClassID )
  94. {
  95. return E_NOTIMPL;
  96. }
  97. STDMETHODIMP CPCHQueryResultCollection::IsDirty()
  98. {
  99. return S_FALSE;
  100. }
  101. STDMETHODIMP CPCHQueryResultCollection::Load( /*[in]*/ IStream *pStm )
  102. {
  103. MPC::Serializer_IStream stream ( pStm );
  104. MPC::Serializer_Buffering stream2( stream );
  105. return pStm ? Load( stream2 ) : E_POINTER;
  106. }
  107. STDMETHODIMP CPCHQueryResultCollection::Save( /*[in]*/ IStream *pStm, /*[in]*/ BOOL fClearDirty )
  108. {
  109. HRESULT hr;
  110. MPC::Serializer_IStream stream ( pStm );
  111. MPC::Serializer_Buffering stream2( stream );
  112. if(pStm)
  113. {
  114. if(SUCCEEDED(hr = Save( stream2 ))) hr = stream2.Flush();
  115. }
  116. else
  117. {
  118. hr = E_POINTER;
  119. }
  120. return hr;
  121. }
  122. STDMETHODIMP CPCHQueryResultCollection::GetSizeMax( /*[out]*/ ULARGE_INTEGER *pcbSize )
  123. {
  124. return E_NOTIMPL;
  125. }
  126. ////////////////////////////////////////
  127. int CPCHQueryResultCollection::Size() const
  128. {
  129. return m_results.size();
  130. }
  131. void CPCHQueryResultCollection::Erase()
  132. {
  133. CPCHBaseCollection::Erase();
  134. MPC::ReleaseAll( m_results );
  135. }
  136. HRESULT CPCHQueryResultCollection::Load( /*[in]*/ MPC::Serializer& streamIn )
  137. {
  138. __HCP_FUNC_ENTRY( "CPCHQueryResultCollection::Load" );
  139. HRESULT hr;
  140. CComPtr<CPCHQueryResult> item;
  141. DWORD dwVer;
  142. int iCount;
  143. Erase();
  144. if(FAILED(streamIn >> dwVer ) || dwVer != l_dwVersion) __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  145. if(FAILED(streamIn >> iCount) ) __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  146. for(int i=0; i<iCount; i++)
  147. {
  148. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateItem( &item ));
  149. __MPC_EXIT_IF_METHOD_FAILS(hr, item->Load( streamIn ));
  150. item.Release();
  151. }
  152. hr = S_OK;
  153. __HCP_FUNC_CLEANUP;
  154. __HCP_FUNC_EXIT(hr);
  155. }
  156. HRESULT CPCHQueryResultCollection::Save( /*[in]*/ MPC::Serializer& streamOut ) const
  157. {
  158. __HCP_FUNC_ENTRY( "CPCHQueryResultCollection::Save" );
  159. HRESULT hr;
  160. Iter it;
  161. DWORD dwVer = l_dwVersion;
  162. int iCount = m_results.size();
  163. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << dwVer );
  164. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << iCount );
  165. for(it = m_results.begin(); it != m_results.end(); it++)
  166. {
  167. __MPC_EXIT_IF_METHOD_FAILS(hr, (*it)->Save( streamOut ));
  168. }
  169. hr = S_OK;
  170. __HCP_FUNC_CLEANUP;
  171. __HCP_FUNC_EXIT(hr);
  172. }
  173. ////////////////////////////////////////////////////////////////////////////////
  174. HRESULT CPCHQueryResultCollection::CreateItem( /*[out]*/ CPCHQueryResult* *item )
  175. {
  176. __HCP_FUNC_ENTRY( "CPCHQueryResultCollection::CreateItem" );
  177. HRESULT hr;
  178. CComPtr<CPCHQueryResult> hpcqr;
  179. __MPC_PARAMCHECK_BEGIN(hr)
  180. __MPC_PARAMCHECK_POINTER_AND_SET(item,NULL);
  181. __MPC_PARAMCHECK_END();
  182. //
  183. // Create a new item and link it to the system.
  184. //
  185. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &hpcqr )); (*item = hpcqr)->AddRef();
  186. __MPC_EXIT_IF_METHOD_FAILS(hr, AddItem( hpcqr ));
  187. m_results.push_back( hpcqr.Detach() );
  188. hr = S_OK;
  189. __HCP_FUNC_CLEANUP;
  190. __HCP_FUNC_EXIT(hr);
  191. }
  192. HRESULT CPCHQueryResultCollection::GetItem( /*[in]*/ long lPos, /*[out]*/ CPCHQueryResult* *item )
  193. {
  194. __HCP_FUNC_ENTRY( "CPCHQueryResultCollection::GetItem" );
  195. HRESULT hr;
  196. Iter it;
  197. __MPC_PARAMCHECK_BEGIN(hr)
  198. __MPC_PARAMCHECK_POINTER_AND_SET(item,NULL);
  199. __MPC_PARAMCHECK_END();
  200. it = m_results.begin();
  201. while(1)
  202. {
  203. if(it == m_results.end())
  204. {
  205. __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
  206. }
  207. if(lPos-- == 0) break;
  208. it++;
  209. }
  210. (*item = *it)->AddRef();
  211. hr = S_OK;
  212. __HCP_FUNC_CLEANUP;
  213. __HCP_FUNC_EXIT(hr);
  214. }
  215. /////////////////////////////////////////////////////////////////////////////
  216. HRESULT CPCHQueryResultCollection::LoadFromCache( /*[in]*/ IStream* stream )
  217. {
  218. __HCP_FUNC_ENTRY( "CPCHQueryResultCollection::LoadFromCache" );
  219. HRESULT hr;
  220. MPC::Serializer_IStream streamReal( stream );
  221. MPC::Serializer_Buffering streamBuf ( streamReal );
  222. Erase();
  223. __MPC_EXIT_IF_METHOD_FAILS(hr, Load( streamBuf ));
  224. hr = S_OK;
  225. __HCP_FUNC_CLEANUP;
  226. __HCP_FUNC_EXIT(hr);
  227. }
  228. HRESULT CPCHQueryResultCollection::SaveToCache( /*[in]*/ IStream* stream ) const
  229. {
  230. __HCP_FUNC_ENTRY( "CPCHQueryResultCollection::SaveToCache" );
  231. HRESULT hr;
  232. MPC::Serializer_IStream streamReal( stream );
  233. MPC::Serializer_Buffering streamBuf ( streamReal );
  234. __MPC_EXIT_IF_METHOD_FAILS(hr, Save( streamBuf ));
  235. __MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf.Flush());
  236. hr = S_OK;
  237. __HCP_FUNC_CLEANUP;
  238. __HCP_FUNC_EXIT(hr);
  239. }
  240. HRESULT CPCHQueryResultCollection::Sort( /*[in]*/ SortMode mode, /*[in]*/ int iLimit )
  241. {
  242. __HCP_FUNC_ENTRY( "CPCHQueryResultCollection::Sort" );
  243. HRESULT hr;
  244. ElementHolder* ptr;
  245. ElementHolder* rgBuf = NULL;
  246. int iSize = m_results.size();
  247. int i;
  248. if(iSize > 1)
  249. {
  250. ElementSorter sorted( mode );
  251. Iter it;
  252. __MPC_EXIT_IF_ALLOC_FAILS(hr, rgBuf, new ElementHolder[iSize]);
  253. for(i=0, ptr=rgBuf, it=m_results.begin(); i<iSize && it!=m_results.end(); i++, ptr++, it++)
  254. {
  255. CPCHQueryResult* obj = *it;
  256. ptr->obj = obj; obj->AddRef();
  257. ptr->pos = i;
  258. }
  259. std::sort( rgBuf, ptr, sorted );
  260. if(iLimit < 0 || iLimit > iSize) iLimit = iSize;
  261. Erase();
  262. for(i=0, ptr=rgBuf; i<iLimit; i++, ptr++)
  263. {
  264. __MPC_EXIT_IF_METHOD_FAILS(hr, AddItem( ptr->obj ));
  265. m_results.push_back( ptr->obj ); ptr->obj = NULL;
  266. }
  267. }
  268. hr = S_OK;
  269. __HCP_FUNC_CLEANUP;
  270. if(rgBuf)
  271. {
  272. for(i=0, ptr=rgBuf; i<iSize; i++, ptr++)
  273. {
  274. if(ptr->obj) ptr->obj->Release();
  275. }
  276. delete [] rgBuf;
  277. }
  278. __HCP_FUNC_EXIT(hr);
  279. }