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.

496 lines
13 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2001.
  5. //
  6. // File: DREP.CXX
  7. //
  8. // Contents: Data Repository
  9. //
  10. // Classes: CDataRepository
  11. //
  12. // History: 18-Apr-91 BartoszM Created
  13. // 03-June-91 t-WadeR Added PutStream, PutPhrase, PutWord
  14. // 01-July-91 t-WadeR Ignores data with invalid property.
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <pch.cxx>
  18. #pragma hdrstop
  19. #include <propvar.h>
  20. #include <drep.hxx>
  21. #include <lang.hxx>
  22. #include <streams.hxx>
  23. #include <pfilter.hxx>
  24. #include <keymak.hxx>
  25. #include <pidmap.hxx>
  26. #include <codepage.hxx>
  27. #include "psource.hxx"
  28. #if CIDBG == 1
  29. CCumulTimer::~CCumulTimer()
  30. {
  31. if (_count)
  32. {
  33. ciDebugOut (( DEB_ITRACE, "%ws:\n", _szActivity ));
  34. ciDebugOut (( DEB_ITRACE, "\taverage %d ms, count %d, total time %d ms\n",
  35. _totalTime/_count, _count, _totalTime ));
  36. }
  37. }
  38. #endif //CIDBG
  39. //+---------------------------------------------------------------------------
  40. //
  41. // Member: CDataRepository::CDataRepository
  42. //
  43. // Arguments: [krep] - the key repository
  44. // [langlist] - the language list
  45. // [langId] - language
  46. // [fuzzy] - the fuzzy flag
  47. //
  48. // History: 18-Apr-91 BartoszM Created
  49. // 08-May-91 t-WadeR Added default language
  50. // 03-June-91 t-WadeR rewritten for input-driven pipeline
  51. // 14-Sep-92 AmyA Added pCat
  52. //
  53. //----------------------------------------------------------------------------
  54. CDataRepository::CDataRepository (
  55. PKeyRepository& krep, IPhraseSink *pPhraseSink,
  56. BOOL fQuery, ULONG fuzzy, CPidMapper & pidMap,
  57. CLangList & langList )
  58. : _krep (krep),
  59. _valueNorm (krep),
  60. _fQuery(fQuery),
  61. _ulGenerateMethod(fuzzy),
  62. _pPhraseSink(pPhraseSink),
  63. _pidMap(pidMap),
  64. _lcidSystemDefault( GetSystemDefaultLCID() ),
  65. _langList(langList),
  66. _pid( pidInvalid ),
  67. _lcid( lcidInvalid ),
  68. _prevPid( 0 ), // Different than _pid
  69. _prevLcid( 0 ), // Different than _lcid
  70. _cwcFoldedPhrase( 0 )
  71. #if CIDBG == 1
  72. , timerBind ( L"Binding" )
  73. , timerNoBind ( L"Creating filter without binding" )
  74. , timerFilter ( L"Filtering" )
  75. #endif
  76. {
  77. }
  78. //+---------------------------------------------------------------------------
  79. //
  80. // Member: CDataRepository::PutStream
  81. //
  82. // Synopsis: Passes stream to key maker to be added to key repository
  83. //
  84. // History: 03-June-91 t-WadeR Created
  85. // 18-Nov-92 AmyA Overloaded
  86. //
  87. //----------------------------------------------------------------------------
  88. void CDataRepository::PutStream ( TEXT_SOURCE * stm )
  89. {
  90. if ( LoadKeyMaker() )
  91. {
  92. Win4Assert( !_xKeyMaker.IsNull() );
  93. _xKeyMaker->PutStream ( _occArray.Get(_pid), stm );
  94. }
  95. }
  96. //+---------------------------------------------------------------------------
  97. //
  98. // Member: CDataRepository::PutPhrase
  99. //
  100. // Synopsis: Passes ASCII string of words to key maker to be added to
  101. // key repository
  102. //
  103. // History: 23-Sept-92 AmyA Created
  104. //
  105. //----------------------------------------------------------------------------
  106. void CDataRepository::PutPhrase ( const char* str, unsigned cc )
  107. {
  108. ULONG cwcOut = cc * 2 + 2;
  109. WCHAR *pwcOut = new WCHAR[cwcOut];
  110. ULONG cwcActual = 0;
  111. do
  112. {
  113. cwcActual = MultiByteToWideChar( _ulCodePage,
  114. 0,
  115. str,
  116. cc,
  117. pwcOut,
  118. cwcOut );
  119. if ( cwcActual == 0 )
  120. {
  121. delete[] pwcOut;
  122. pwcOut = 0;
  123. if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
  124. {
  125. cwcOut *= 2;
  126. pwcOut = new WCHAR[cwcOut];
  127. }
  128. else
  129. THROW( CException() );
  130. }
  131. } while ( cwcActual == 0 );
  132. XArray<WCHAR> xOut;
  133. xOut.Set( cwcOut, pwcOut );
  134. PutPhrase( pwcOut, cwcActual );
  135. }
  136. //+---------------------------------------------------------------------------
  137. //
  138. // Member: CDataRepository::PutPhrase
  139. //
  140. // Synopsis: Passes unicode string of words to key maker to be added to
  141. // key repository
  142. //
  143. // History: 23-Sept-92 AmyA Created
  144. //
  145. //----------------------------------------------------------------------------
  146. void CDataRepository::PutPhrase ( const WCHAR* str, unsigned cwc )
  147. {
  148. if ( 0 != str && cwc > 0 && LoadKeyMaker() )
  149. {
  150. //
  151. // Normalize to precomposed Unicode
  152. //
  153. _xwcsFoldedPhrase.ReSize( cwc );
  154. ULONG cwcFolded = FoldStringW( MAP_PRECOMPOSED,
  155. str,
  156. cwc,
  157. _xwcsFoldedPhrase.Get(),
  158. cwc );
  159. if ( cwcFolded == 0 )
  160. {
  161. Win4Assert( GetLastError() != ERROR_INSUFFICIENT_BUFFER );
  162. THROW( CException() );
  163. }
  164. _cwcFoldedPhrase = cwcFolded;
  165. CPhraseSource s( _xwcsFoldedPhrase.GetPointer(), cwcFolded );
  166. Win4Assert( !_xKeyMaker.IsNull() );
  167. _xKeyMaker->PutStream ( _occArray.Get(_pid), &s );
  168. }
  169. }
  170. //+---------------------------------------------------------------------------
  171. //
  172. // Member: CDataRepository::PutPropName
  173. //
  174. // Arguments: [strProp] -- name of the property
  175. //
  176. // History: 18-Apr-91 BartoszM Created
  177. // 01-June-91 t-WadeR Ignores data with invalid property
  178. // 21-Feb-95 DwightKr Added fake property id mapping
  179. //
  180. //----------------------------------------------------------------------------
  181. BOOL CDataRepository::PutPropName ( CFullPropSpec const & Prop )
  182. {
  183. //
  184. // Find the pid
  185. //
  186. PROPID fakePid = _pidMap.NameToPid( Prop );
  187. return PutPropId( fakePid );
  188. }
  189. //+---------------------------------------------------------------------------
  190. //----------------------------------------------------------------------------
  191. BOOL CDataRepository::PutPropId ( PROPID fakePid )
  192. {
  193. _prevPid = _pid;
  194. if ( fakePid == pidInvalid )
  195. {
  196. _pid = pidInvalid;
  197. }
  198. else
  199. {
  200. _pid = _pidMap.PidToRealPid( fakePid );
  201. if ( !_krep.PutPropId( _pid ) )
  202. {
  203. ciDebugOut(( DEB_WARN, "Key repository didn't accept pid %u\n", _pid ));
  204. _pid = pidInvalid;
  205. }
  206. }
  207. return (pidInvalid != _pid);
  208. }
  209. //+---------------------------------------------------------------------------
  210. //
  211. // Member: CDataRepository::PutLanguage
  212. //
  213. // Synopsis: if the lcid is different, it frees the current lang. dependent
  214. // key maker, and gets a new one
  215. //
  216. // Arguments: [lcid] -- language descriptor
  217. //
  218. // History: 18-Apr-91 BartoszM Created
  219. // 03-June-91 t-WadeR Changed to use CLangDepKeyMaker pool.
  220. //
  221. //----------------------------------------------------------------------------
  222. BOOL CDataRepository::PutLanguage ( LCID lcid )
  223. {
  224. _prevLcid = _lcid;
  225. //
  226. // Special cases for language: system default and user default.
  227. //
  228. if ( lcid == LOCALE_SYSTEM_DEFAULT )
  229. _lcid = GetSystemDefaultLCID();
  230. else if ( lcid == LOCALE_USER_DEFAULT )
  231. _lcid = GetUserDefaultLCID();
  232. else
  233. _lcid = lcid;
  234. //
  235. // Set codepage, for conversion of narrow strings.
  236. //
  237. if ( _prevLcid != _lcid )
  238. {
  239. _ulCodePage = LocaleToCodepage( _lcid );
  240. }
  241. return TRUE;
  242. }
  243. //+---------------------------------------------------------------------------
  244. //
  245. // Member: CDataRepository::PutValue
  246. //
  247. // Synopsis: Store a property value.
  248. //
  249. // Arguments: [var] -- Value
  250. //
  251. // History: 08-Feb-94 KyleP Added header
  252. //
  253. //----------------------------------------------------------------------------
  254. void CDataRepository::PutValue( CStorageVariant const & var )
  255. {
  256. //
  257. // Textual values are special. They are treated as contents, and
  258. // thus need language identification and word breaking. Unlike contents,
  259. // we do not provide support for choosing the language.
  260. //
  261. switch ( var.Type() )
  262. {
  263. case VT_LPWSTR:
  264. {
  265. unsigned cwc = 0;
  266. if ( 0 != var.GetLPWSTR() )
  267. {
  268. cwc = wcslen( var.GetLPWSTR() );
  269. }
  270. if (cwc > 0)
  271. PutPhrase( var.GetLPWSTR(), cwc + 1);
  272. break;
  273. }
  274. case VT_LPSTR:
  275. {
  276. unsigned cb = 0;
  277. if ( 0 != var.GetLPSTR() )
  278. {
  279. cb = strlen( var.GetLPSTR() );
  280. }
  281. if (cb > 0)
  282. PutPhrase( var.GetLPSTR(), cb + 1);
  283. break;
  284. }
  285. case VT_BSTR :
  286. {
  287. if ( ( 0 != var.GetBSTR() ) &&
  288. ( 0 != BSTRLEN( var.GetBSTR() ) ) )
  289. {
  290. PutPhrase( var.GetBSTR(),
  291. 1 + ( BSTRLEN( var.GetBSTR() ) / sizeof WCHAR ) );
  292. }
  293. break;
  294. }
  295. case VT_VECTOR | VT_LPWSTR:
  296. {
  297. for ( ULONG j = 0; j < var.Count(); j++ )
  298. {
  299. unsigned cb = 0;
  300. if ( 0 != var.GetLPWSTR(j) )
  301. {
  302. cb = wcslen( var.GetLPWSTR(j) );
  303. }
  304. if (cb > 0)
  305. {
  306. PutPhrase( var.GetLPWSTR(j), cb + 1);
  307. }
  308. }
  309. break;
  310. }
  311. case VT_VECTOR | VT_BSTR:
  312. {
  313. for ( ULONG j = 0; j < var.Count(); j++ )
  314. {
  315. if ( ( 0 != var.GetBSTR(j) ) &&
  316. ( 0 != BSTRLEN( var.GetBSTR(j) ) ) )
  317. {
  318. PutPhrase( var.GetBSTR(j),
  319. 1 + ( BSTRLEN( var.GetBSTR(j) ) / sizeof WCHAR ) );
  320. }
  321. }
  322. break;
  323. }
  324. case VT_VECTOR | VT_LPSTR:
  325. {
  326. for ( ULONG j = 0; j < var.Count(); j++ )
  327. {
  328. unsigned cb = 0;
  329. if ( 0 != var.GetLPSTR(j) )
  330. {
  331. cb = strlen( var.GetLPSTR(j) );
  332. }
  333. if (cb > 0)
  334. {
  335. PutPhrase( var.GetLPSTR(j), cb + 1);
  336. }
  337. }
  338. break;
  339. }
  340. case VT_VECTOR | VT_VARIANT :
  341. {
  342. for ( ULONG j=0; j < var.Count(); j++ )
  343. {
  344. ciDebugOut (( DEB_ITRACE, "Filtering vector variant[%d] of type 0x%x\n",
  345. j, (ULONG) var.GetVARIANT(j).Type() ));
  346. PutValue( (CStorageVariant const &)var.GetVARIANT(j) );
  347. }
  348. break;
  349. }
  350. default:
  351. _valueNorm.PutValue( _pid, _occArray.Get(_pid), var );
  352. break;
  353. }
  354. }
  355. //+---------------------------------------------------------------------------
  356. //
  357. // Member: CDataRepository::ContainedNoiseWords
  358. //
  359. // Returns: TRUE if any text sent to repository had a noise word in it.
  360. //
  361. // History: 03-Oct-95 KyleP Created
  362. //
  363. //----------------------------------------------------------------------------
  364. BOOL CDataRepository::ContainedNoiseWords()
  365. {
  366. if ( _xKeyMaker.IsNull() )
  367. return FALSE;
  368. return _xKeyMaker->ContainedNoiseWords();
  369. }
  370. //+---------------------------------------------------------------------------
  371. //
  372. // Member: CDataRepository::LoadKeyMaker, private
  373. //
  374. // Synopsis: Loads new key maker, if necessary
  375. //
  376. // Returns: TRUE if an appropriate key maker was located (and loaded).
  377. //
  378. // History: 05-Jan-98 KyleP Created
  379. //
  380. //----------------------------------------------------------------------------
  381. BOOL CDataRepository::LoadKeyMaker()
  382. {
  383. if ( pidInvalid == _pid || lcidInvalid == _lcid )
  384. return FALSE;
  385. if ( _pid == _prevPid && _lcid == _prevLcid )
  386. {
  387. Win4Assert( !_xKeyMaker.IsNull() );
  388. return TRUE;
  389. }
  390. //
  391. // Locate an appropriate Key Maker
  392. //
  393. if ( _xKeyMaker.IsNull() || !_xKeyMaker->Supports( _pid, _lcid ) )
  394. {
  395. delete _xKeyMaker.Acquire();
  396. _xKeyMaker.Set( new CKeyMaker( _lcid, _pid, _krep, _pPhraseSink, _fQuery, _ulGenerateMethod, _langList ) );
  397. }
  398. return TRUE;
  399. }
  400. //+---------------------------------------------------------------------------
  401. //
  402. // Member: CDataRepository::NormalizeWStr - Public
  403. //
  404. // Synopsis: Normalizes a UniCode string
  405. //
  406. // Arguments: [pbOutBuf] -- output buffer.
  407. // [pcbOutBuf] - pointer to output count of bytes.
  408. //
  409. // History: 10-Feb-2000 KitmanH Created
  410. //
  411. //----------------------------------------------------------------------------
  412. void CDataRepository::NormalizeWStr( BYTE *pbOutBuf, unsigned *pcbOutBuf )
  413. {
  414. // Chop off the trailing null character
  415. if ( 0 == _xwcsFoldedPhrase[_cwcFoldedPhrase-1] )
  416. _cwcFoldedPhrase--;
  417. Win4Assert( _cwcFoldedPhrase > 0 );
  418. ciDebugOut(( DEB_ITRACE, "CDdataRepository::NormailizeWStr: %ws, %d\n",
  419. _xwcsFoldedPhrase.Get(),
  420. _cwcFoldedPhrase ));
  421. _xKeyMaker->NormalizeWStr( _xwcsFoldedPhrase.Get(),
  422. _cwcFoldedPhrase,
  423. pbOutBuf,
  424. pcbOutBuf );
  425. }