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.

4595 lines
112 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: Compare.cxx
  7. //
  8. // Contents: Comparator class for property sets.
  9. //
  10. // Classes: CComparePropSets
  11. //
  12. // History: 07-Jun-92 KyleP Created
  13. // 07-Apr-93 KyleP Convert to CairOle
  14. // 02-Nov-93 KyleP Added allmost all VT_ types
  15. //
  16. // Notes: The following comparisons are suppored
  17. //
  18. // Variant Equality Relational Bitwise
  19. // ----------- ----------- ---------- -------
  20. //
  21. // VT_EMPTY X
  22. // VT_NULL X
  23. // VT_I2 X X X
  24. // VT_I4 X X X
  25. // VT_R4 X X
  26. // VT_R8 X X
  27. // VT_CY X X
  28. // VT_DATE X X
  29. // VT_BSTR X X
  30. // VT_DISPATCH -
  31. // VT_ERROR X X X
  32. // VT_BOOL X
  33. // VT_VARIANT X X
  34. // VT_UNKNOWN -
  35. // VT_DECIMAL X X
  36. // VT_I1 X X X
  37. // VT_UI1 X X X
  38. // VT_UI2 X X X
  39. // VT_UI4 X X X
  40. // VT_I8 X X X
  41. // VT_UI8 X X X
  42. // VT_INT X X X
  43. // VT_UINT X X X
  44. // VT_VOID -
  45. // VT_HRESULT X X X
  46. // VT_PTR -
  47. // VT_SAFEARRAY -
  48. // VT_CARRAY -
  49. // VT_USERDEFINED -
  50. // VT_LPSTR X X
  51. // VT_LPWSTR X X
  52. // VT_FILETIME X X
  53. // VT_BLOB X X
  54. // VT_STREAM
  55. // VT_STORAGE
  56. // VT_STREAMED_OBJECT
  57. // VT_STORED_OBJECT
  58. // VT_BLOB_OBJECT X X
  59. // VT_CF X X
  60. // VT_CLSID X
  61. //
  62. //
  63. // The following are OLE-DB datatypes.
  64. //
  65. // Variant Equality Vector
  66. // ----------- ----------- ------
  67. //
  68. // DBTYPE_EMPTY X
  69. // DBTYPE_NULL X
  70. // DBTYPE_I1 X X
  71. // DBTYPE_UI1 X X
  72. // DBTYPE_I2 X X
  73. // DBTYPE_UI2 X X
  74. // DBTYPE_I4 X X
  75. // DBTYPE_UI4 X X
  76. // DBTYPE_R4 X X
  77. // DBTYPE_R8 X X
  78. // DBTYPE_CY X X
  79. // DBTYPE_DATE X X
  80. // DBTYPE_BSTR X
  81. // DBTYPE_DISPATCH
  82. // DBTYPE_ERROR X
  83. // DBTYPE_BOOL X
  84. // DBTYPE_VARIANT X X
  85. // DBTYPE_UNKNOWN X
  86. // DBTYPE_I8 X X
  87. // DBTYPE_GUID X
  88. // DBTYPE_BYTES X X
  89. // DBTYPE_STR X X
  90. // DBTYPE_WSTR X X
  91. //
  92. //--------------------------------------------------------------------------
  93. #include <pch.cxx>
  94. #pragma hdrstop
  95. #include <compare.hxx>
  96. #include <coldesc.hxx>
  97. #include <propvar.h>
  98. CComparators VariantCompare;
  99. DBTYPEENUM dbVector(DBTYPEENUM vt)
  100. {
  101. return (DBTYPEENUM) (DBTYPE_VECTOR | vt);
  102. }
  103. //
  104. // DEFAULT. Used for optimization in looped comparisons. If we can't
  105. // determine the way to compare, then use this default.
  106. //
  107. int VT_DEFAULT_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  108. {
  109. return( 0 );
  110. }
  111. //
  112. // VT_EMPTY
  113. //
  114. int VT_EMPTY_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  115. {
  116. return( 0 );
  117. }
  118. BOOL VT_EMPTY_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  119. {
  120. return( TRUE );
  121. }
  122. BOOL VT_EMPTY_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  123. {
  124. return( FALSE );
  125. }
  126. //
  127. // VT_NULL
  128. //
  129. int VT_NULL_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  130. {
  131. return( 0 );
  132. }
  133. BOOL VT_NULL_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  134. {
  135. return( TRUE );
  136. }
  137. BOOL VT_NULL_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  138. {
  139. return( FALSE );
  140. }
  141. //
  142. // VT_I2
  143. //
  144. int VT_I2_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  145. {
  146. return( v1.iVal - v2.iVal );
  147. }
  148. BOOL VT_I2_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  149. {
  150. return( v1.iVal < v2.iVal );
  151. }
  152. BOOL VT_I2_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  153. {
  154. return( v1.iVal <= v2.iVal );
  155. }
  156. BOOL VT_I2_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  157. {
  158. return( v1.iVal >= v2.iVal );
  159. }
  160. BOOL VT_I2_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  161. {
  162. return( v1.iVal > v2.iVal );
  163. }
  164. BOOL VT_I2_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  165. {
  166. return( v1.iVal == v2.iVal );
  167. }
  168. BOOL VT_I2_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  169. {
  170. return( v1.iVal != v2.iVal );
  171. }
  172. BOOL VT_I2_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  173. {
  174. return( (v1.iVal & v2.iVal) == v2.iVal );
  175. }
  176. BOOL VT_I2_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  177. {
  178. return( (v1.iVal & v2.iVal) != 0 );
  179. }
  180. //
  181. // VT_I4
  182. //
  183. int VT_I4_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  184. {
  185. return ( v1.lVal > v2.lVal ) ? 1 : ( v1.lVal < v2.lVal ) ? -1 : 0;
  186. }
  187. BOOL VT_I4_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  188. {
  189. return( v1.lVal < v2.lVal );
  190. }
  191. BOOL VT_I4_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  192. {
  193. return( v1.lVal <= v2.lVal );
  194. }
  195. BOOL VT_I4_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  196. {
  197. return( v1.lVal >= v2.lVal );
  198. }
  199. BOOL VT_I4_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  200. {
  201. return( v1.lVal > v2.lVal );
  202. }
  203. BOOL VT_I4_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  204. {
  205. return( v1.lVal == v2.lVal );
  206. }
  207. BOOL VT_I4_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  208. {
  209. return( v1.lVal != v2.lVal );
  210. }
  211. BOOL VT_I4_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  212. {
  213. return( (v1.lVal & v2.lVal) == v2.lVal );
  214. }
  215. BOOL VT_I4_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  216. {
  217. return( (v1.lVal & v2.lVal) != 0 );
  218. }
  219. //
  220. // VT_R4
  221. //
  222. //
  223. // We can't use floating point in the kernel. Luckily, it's easy to
  224. // fake comparisons on floating point. The format of an IEEE floating
  225. // point number is:
  226. //
  227. // <sign bit> <biased exponent> <normalized mantissa>
  228. //
  229. // Because the exponent is biased, after flipping the sign bit we can
  230. // make all comparisons as if the numbers were unsigned long.
  231. //
  232. ULONG const R4_SignBit = 0x80000000;
  233. int VT_R4_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  234. {
  235. // axp (not x86) generates exceptions when floating point numbers
  236. // don't look like ieee floating point numbers. This can happen
  237. // with bogus queries or bogus values stored in properties or the
  238. // property store.
  239. #if (_X86_ == 1)
  240. return ( v1.fltVal > v2.fltVal ) ? 1 :
  241. ( v1.fltVal < v2.fltVal ) ? -1 : 0;
  242. #else
  243. ULONG u1 = v1.ulVal ^ R4_SignBit;
  244. ULONG u2 = v2.ulVal ^ R4_SignBit;
  245. if ( (v1.ulVal & v2.ulVal & R4_SignBit) != 0 )
  246. return ( ( u1 > u2 ) ? -1 : ( u1 < u2 ) ? 1 : 0 );
  247. else
  248. return ( ( u1 > u2 ) ? 1 : ( u1 < u2 ) ? -1 : 0 );
  249. #endif
  250. }
  251. BOOL VT_R4_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  252. {
  253. return VT_R4_Compare( v1, v2 ) < 0;
  254. }
  255. BOOL VT_R4_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  256. {
  257. return VT_R4_Compare( v1, v2 ) <= 0;
  258. }
  259. BOOL VT_R4_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  260. {
  261. return VT_R4_Compare( v1, v2 ) >= 0;
  262. }
  263. BOOL VT_R4_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  264. {
  265. return VT_R4_Compare( v1, v2 ) > 0;
  266. }
  267. BOOL VT_R4_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  268. {
  269. return( v1.ulVal == v2.ulVal );
  270. }
  271. BOOL VT_R4_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  272. {
  273. return( v1.ulVal != v2.ulVal );
  274. }
  275. //
  276. // VT_R8
  277. //
  278. LONGLONG const R8_SignBit = 0x8000000000000000;
  279. int VT_R8_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  280. {
  281. // axp (not x86) generates exceptions when floating point numbers
  282. // don't look like ieee floating point numbers. This can happen
  283. // with bogus queries or bogus values stored in properties or the
  284. // property store.
  285. #if (_X86_ == 1)
  286. return ( v1.dblVal > v2.dblVal ) ? 1 :
  287. ( v1.dblVal < v2.dblVal ) ? -1 : 0;
  288. #else
  289. if ( (v1.uhVal.QuadPart & v2.uhVal.QuadPart & R8_SignBit) != 0 )
  290. return( (v1.uhVal.QuadPart ^ R8_SignBit) < (v2.uhVal.QuadPart ^ R8_SignBit) ? 1 :
  291. (v1.uhVal.QuadPart ^ R8_SignBit) == (v2.uhVal.QuadPart ^ R8_SignBit) ? 0 :
  292. -1 );
  293. else
  294. return( (v1.uhVal.QuadPart ^ R8_SignBit) > (v2.uhVal.QuadPart ^ R8_SignBit) ? 1 :
  295. (v1.uhVal.QuadPart ^ R8_SignBit) == (v2.uhVal.QuadPart ^ R8_SignBit) ? 0 :
  296. -1 );
  297. #endif // 0
  298. }
  299. BOOL VT_R8_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  300. {
  301. return VT_R8_Compare( v1, v2 ) < 0;
  302. }
  303. BOOL VT_R8_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  304. {
  305. return VT_R8_Compare( v1, v2 ) <= 0;
  306. }
  307. BOOL VT_R8_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  308. {
  309. return VT_R8_Compare( v1, v2 ) >= 0;
  310. }
  311. BOOL VT_R8_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  312. {
  313. return VT_R8_Compare( v1, v2 ) > 0;
  314. }
  315. BOOL VT_R8_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  316. {
  317. return( v1.uhVal.QuadPart == v2.uhVal.QuadPart );
  318. }
  319. BOOL VT_R8_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  320. {
  321. return( v1.uhVal.QuadPart != v2.uhVal.QuadPart );
  322. }
  323. //
  324. // VT_BSTR
  325. //
  326. int VT_BSTR_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  327. {
  328. BSTR const pxv1 = v1.bstrVal;
  329. BSTR const pxv2 = v2.bstrVal;
  330. ULONG len = BSTRLEN(pxv1);
  331. if ( BSTRLEN(pxv2) < len )
  332. len = BSTRLEN(pxv2);
  333. int iCmp = _wcsnicmp( pxv1, pxv2, len / sizeof (OLECHAR) );
  334. if ( iCmp != 0 || BSTRLEN(pxv1) == BSTRLEN(pxv2) )
  335. return( iCmp );
  336. if ( BSTRLEN(pxv1) > BSTRLEN(pxv2) )
  337. return( 1 );
  338. else
  339. return( -1 );
  340. }
  341. BOOL VT_BSTR_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  342. {
  343. return( VT_BSTR_Compare( v1, v2 ) < 0 );
  344. }
  345. BOOL VT_BSTR_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  346. {
  347. return( VT_BSTR_Compare( v1, v2 ) <= 0 );
  348. }
  349. BOOL VT_BSTR_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  350. {
  351. return( VT_BSTR_Compare( v1, v2 ) >= 0 );
  352. }
  353. BOOL VT_BSTR_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  354. {
  355. return( VT_BSTR_Compare( v1, v2 ) > 0 );
  356. }
  357. BOOL VT_BSTR_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  358. {
  359. BSTR const pxv1 = v1.bstrVal;
  360. BSTR const pxv2 = v2.bstrVal;
  361. return( BSTRLEN(pxv1) == BSTRLEN(pxv2) &&
  362. _wcsnicmp( pxv1, pxv2, BSTRLEN(pxv1) / sizeof (OLECHAR) ) == 0 );
  363. }
  364. BOOL VT_BSTR_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  365. {
  366. BSTR const pxv1 = v1.bstrVal;
  367. BSTR const pxv2 = v2.bstrVal;
  368. return( BSTRLEN(pxv1) != BSTRLEN(pxv2) ||
  369. _wcsnicmp( pxv1, pxv2, BSTRLEN(pxv1) / sizeof (OLECHAR) ) != 0 );
  370. }
  371. //
  372. // VT_BOOL
  373. //
  374. int VT_BOOL_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  375. {
  376. if (v1.boolVal == 0)
  377. if (v2.boolVal == 0)
  378. return( 0 );
  379. else
  380. return( -1 );
  381. else
  382. if (v2.boolVal == 0)
  383. return( 1 );
  384. else
  385. return( 0 );
  386. }
  387. BOOL VT_BOOL_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  388. {
  389. return( ((v1.boolVal==0) && (v2.boolVal==0)) ||
  390. ((v1.boolVal!=0) && (v2.boolVal!=0)) );
  391. }
  392. BOOL VT_BOOL_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  393. {
  394. return( !VT_BOOL_EQ( v1, v2 ) );
  395. }
  396. //
  397. // VT_VARIANT
  398. //
  399. int VT_VARIANT_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  400. {
  401. if ( v1.vt != v2.vt )
  402. return v1.vt - v2.vt;
  403. FCmp comp = VariantCompare.GetComparator( (VARENUM) v1.vt );
  404. if (0 == comp)
  405. return 0;
  406. else
  407. return comp( v1, v2 );
  408. }
  409. BOOL VT_VARIANT_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  410. {
  411. return VT_VARIANT_Compare( v1, v2 ) < 0;
  412. }
  413. BOOL VT_VARIANT_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  414. {
  415. return VT_VARIANT_Compare( v1, v2 ) <= 0;
  416. }
  417. BOOL VT_VARIANT_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  418. {
  419. return VT_VARIANT_Compare( v1, v2 ) >= 0;
  420. }
  421. BOOL VT_VARIANT_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  422. {
  423. return VT_VARIANT_Compare( v1, v2 ) > 0;
  424. }
  425. BOOL VT_VARIANT_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  426. {
  427. return VT_VARIANT_Compare( v1, v2 ) == 0;
  428. }
  429. BOOL VT_VARIANT_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  430. {
  431. return VT_VARIANT_Compare( v1, v2 ) != 0;
  432. }
  433. //
  434. // VT_DECIMAL
  435. //
  436. int VT_DEC_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  437. {
  438. if ( v1.decVal.sign == v2.decVal.sign &&
  439. v1.decVal.scale == v2.decVal.scale &&
  440. v1.decVal.Hi32 == v2.decVal.Hi32 &&
  441. v1.decVal.Lo64 == v2.decVal.Lo64)
  442. return 0;
  443. int iSign = v1.decVal.sign == DECIMAL_NEG ? -1 : 1;
  444. if ( v1.decVal.sign != v2.decVal.sign )
  445. return iSign;
  446. if ( v1.decVal.scale == v2.decVal.scale )
  447. {
  448. int iRet = 0;
  449. if (v1.decVal.Hi32 != v2.decVal.Hi32)
  450. iRet = (v1.decVal.Hi32 < v2.decVal.Hi32) ? -1 : 1;
  451. else if (v1.decVal.Lo64 != v2.decVal.Lo64)
  452. iRet = (v1.decVal.Lo64 < v2.decVal.Lo64) ? -1 : 1;
  453. return iRet * iSign;
  454. }
  455. double d1;
  456. VarR8FromDec( (DECIMAL*)&v1.decVal, &d1 );
  457. double d2;
  458. VarR8FromDec( (DECIMAL*)&v2.decVal, &d2 );
  459. return (( d1 > d2 ) ? 1 : ( d1 < d2 ) ? -1 : 0);
  460. }
  461. BOOL VT_DEC_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  462. {
  463. return VT_VARIANT_Compare( v1, v2 ) < 0;
  464. }
  465. BOOL VT_DEC_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  466. {
  467. return VT_DEC_Compare( v1, v2 ) <= 0;
  468. }
  469. BOOL VT_DEC_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  470. {
  471. return VT_DEC_Compare( v1, v2 ) >= 0;
  472. }
  473. BOOL VT_DEC_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  474. {
  475. return VT_DEC_Compare( v1, v2 ) > 0;
  476. }
  477. BOOL VT_DEC_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  478. {
  479. return VT_DEC_Compare( v1, v2 ) == 0;
  480. }
  481. BOOL VT_DEC_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  482. {
  483. return VT_DEC_Compare( v1, v2 ) != 0;
  484. }
  485. //
  486. // VT_I1
  487. //
  488. int VT_I1_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  489. {
  490. return( v1.cVal - v2.cVal );
  491. }
  492. BOOL VT_I1_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  493. {
  494. return( v1.cVal < v2.cVal );
  495. }
  496. BOOL VT_I1_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  497. {
  498. return( v1.cVal <= v2.cVal );
  499. }
  500. BOOL VT_I1_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  501. {
  502. return( v1.cVal >= v2.cVal );
  503. }
  504. BOOL VT_I1_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  505. {
  506. return( v1.cVal > v2.cVal );
  507. }
  508. BOOL VT_I1_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  509. {
  510. return( v1.cVal == v2.cVal );
  511. }
  512. BOOL VT_I1_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  513. {
  514. return( v1.cVal != v2.cVal );
  515. }
  516. BOOL VT_I1_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  517. {
  518. return( (v1.cVal & v2.cVal) == v2.cVal );
  519. }
  520. BOOL VT_I1_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  521. {
  522. return( (v1.cVal & v2.cVal) != 0 );
  523. }
  524. //
  525. // VT_UI1
  526. //
  527. int VT_UI1_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  528. {
  529. return( v1.bVal - v2.bVal );
  530. }
  531. BOOL VT_UI1_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  532. {
  533. return( v1.bVal < v2.bVal );
  534. }
  535. BOOL VT_UI1_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  536. {
  537. return( v1.bVal <= v2.bVal );
  538. }
  539. BOOL VT_UI1_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  540. {
  541. return( v1.bVal >= v2.bVal );
  542. }
  543. BOOL VT_UI1_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  544. {
  545. return( v1.bVal > v2.bVal );
  546. }
  547. BOOL VT_UI1_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  548. {
  549. return( v1.bVal == v2.bVal );
  550. }
  551. BOOL VT_UI1_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  552. {
  553. return( v1.bVal != v2.bVal );
  554. }
  555. BOOL VT_UI1_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  556. {
  557. return( (v1.bVal & v2.bVal) == v2.bVal );
  558. }
  559. BOOL VT_UI1_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  560. {
  561. return( (v1.bVal & v2.bVal) != 0 );
  562. }
  563. //
  564. // VT_UI2
  565. //
  566. int VT_UI2_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  567. {
  568. return( v1.uiVal - v2.uiVal );
  569. }
  570. BOOL VT_UI2_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  571. {
  572. return( v1.uiVal < v2.uiVal );
  573. }
  574. BOOL VT_UI2_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  575. {
  576. return( v1.uiVal <= v2.uiVal );
  577. }
  578. BOOL VT_UI2_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  579. {
  580. return( v1.uiVal >= v2.uiVal );
  581. }
  582. BOOL VT_UI2_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  583. {
  584. return( v1.uiVal > v2.uiVal );
  585. }
  586. BOOL VT_UI2_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  587. {
  588. return( v1.uiVal == v2.uiVal );
  589. }
  590. BOOL VT_UI2_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  591. {
  592. return( v1.uiVal != v2.uiVal );
  593. }
  594. BOOL VT_UI2_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  595. {
  596. return( (v1.uiVal & v2.uiVal) == v2.uiVal );
  597. }
  598. BOOL VT_UI2_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  599. {
  600. return( (v1.uiVal & v2.uiVal) != 0 );
  601. }
  602. //
  603. // VT_UI4
  604. //
  605. int VT_UI4_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  606. {
  607. return ( v1.ulVal > v2.ulVal ) ? 1 : ( v1.ulVal < v2.ulVal ) ? -1 : 0;
  608. }
  609. BOOL VT_UI4_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  610. {
  611. return( v1.ulVal < v2.ulVal );
  612. }
  613. BOOL VT_UI4_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  614. {
  615. return( v1.ulVal <= v2.ulVal );
  616. }
  617. BOOL VT_UI4_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  618. {
  619. return( v1.ulVal >= v2.ulVal );
  620. }
  621. BOOL VT_UI4_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  622. {
  623. return( v1.ulVal > v2.ulVal );
  624. }
  625. BOOL VT_UI4_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  626. {
  627. return( v1.ulVal == v2.ulVal );
  628. }
  629. BOOL VT_UI4_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  630. {
  631. return( v1.ulVal != v2.ulVal );
  632. }
  633. BOOL VT_UI4_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  634. {
  635. return( (v1.ulVal & v2.ulVal) == v2.ulVal );
  636. }
  637. BOOL VT_UI4_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  638. {
  639. return( (v1.ulVal & v2.ulVal) != 0 );
  640. }
  641. //
  642. // VT_I8
  643. //
  644. int VT_I8_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  645. {
  646. return( v1.hVal.QuadPart > v2.hVal.QuadPart ? 1 :
  647. v1.hVal.QuadPart == v2.hVal.QuadPart ? 0 :
  648. -1 );
  649. }
  650. BOOL VT_I8_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  651. {
  652. return( v1.hVal.QuadPart < v2.hVal.QuadPart );
  653. }
  654. BOOL VT_I8_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  655. {
  656. return( v1.hVal.QuadPart <= v2.hVal.QuadPart );
  657. }
  658. BOOL VT_I8_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  659. {
  660. return( v1.hVal.QuadPart >= v2.hVal.QuadPart );
  661. }
  662. BOOL VT_I8_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  663. {
  664. return( v1.hVal.QuadPart > v2.hVal.QuadPart );
  665. }
  666. BOOL VT_I8_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  667. {
  668. return( v1.hVal.QuadPart == v2.hVal.QuadPart );
  669. }
  670. BOOL VT_I8_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  671. {
  672. return( v1.hVal.QuadPart != v2.hVal.QuadPart );
  673. }
  674. BOOL VT_I8_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  675. {
  676. return( (v1.hVal.QuadPart & v2.hVal.QuadPart) == v2.hVal.QuadPart );
  677. }
  678. BOOL VT_I8_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  679. {
  680. return( (v1.hVal.QuadPart & v2.hVal.QuadPart) != 0 );
  681. }
  682. //
  683. // VT_UI8
  684. //
  685. int VT_UI8_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  686. {
  687. return( v1.uhVal.QuadPart > v2.uhVal.QuadPart ? 1 :
  688. v1.uhVal.QuadPart == v2.uhVal.QuadPart ? 0 :
  689. -1 );
  690. }
  691. BOOL VT_UI8_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  692. {
  693. return( v1.uhVal.QuadPart < v2.uhVal.QuadPart );
  694. }
  695. BOOL VT_UI8_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  696. {
  697. return( v1.uhVal.QuadPart <= v2.uhVal.QuadPart );
  698. }
  699. BOOL VT_UI8_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  700. {
  701. return( v1.uhVal.QuadPart >= v2.uhVal.QuadPart );
  702. }
  703. BOOL VT_UI8_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  704. {
  705. return( v1.uhVal.QuadPart > v2.uhVal.QuadPart );
  706. }
  707. BOOL VT_UI8_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  708. {
  709. return( v1.uhVal.QuadPart == v2.uhVal.QuadPart );
  710. }
  711. BOOL VT_UI8_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  712. {
  713. return( v1.uhVal.QuadPart != v2.uhVal.QuadPart );
  714. }
  715. BOOL VT_UI8_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  716. {
  717. return( (v1.uhVal.QuadPart & v2.uhVal.QuadPart) == v2.uhVal.QuadPart );
  718. }
  719. BOOL VT_UI8_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  720. {
  721. return( (v1.uhVal.QuadPart & v2.uhVal.QuadPart) != 0 );
  722. }
  723. //
  724. // VT_LPSTR
  725. //
  726. int VT_LPSTR_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  727. {
  728. return ( _stricmp( v1.pszVal, v2.pszVal ) );
  729. }
  730. BOOL VT_LPSTR_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  731. {
  732. int rc = _stricmp( v1.pszVal, v2.pszVal );
  733. return( rc < 0 );
  734. }
  735. BOOL VT_LPSTR_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  736. {
  737. int rc = _stricmp( v1.pszVal, v2.pszVal );
  738. return( rc <= 0 );
  739. }
  740. BOOL VT_LPSTR_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  741. {
  742. int rc = _stricmp( v1.pszVal, v2.pszVal );
  743. return( rc >= 0 );
  744. }
  745. BOOL VT_LPSTR_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  746. {
  747. int rc = _stricmp( v1.pszVal, v2.pszVal );
  748. return( rc > 0 );
  749. }
  750. BOOL VT_LPSTR_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  751. {
  752. return( _stricmp( v1.pszVal, v2.pszVal ) == 0 );
  753. }
  754. BOOL VT_LPSTR_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  755. {
  756. return( _stricmp( v1.pszVal, v2.pszVal ) != 0 );
  757. }
  758. //
  759. // VT_LPWSTR
  760. //
  761. int VT_LPWSTR_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  762. {
  763. int rc = CompareStringW( LOCALE_SYSTEM_DEFAULT,
  764. NORM_IGNORECASE,
  765. v1.pwszVal,
  766. -1,
  767. v2.pwszVal,
  768. -1 );
  769. //
  770. // rc == 1, means less than
  771. // rc == 2, means equal
  772. // rc == 3, means greater than
  773. //
  774. return rc - 2;
  775. }
  776. BOOL VT_LPWSTR_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  777. {
  778. return ( VT_LPWSTR_Compare( v1, v2 ) < 0 );
  779. }
  780. BOOL VT_LPWSTR_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  781. {
  782. return ( VT_LPWSTR_Compare( v1, v2 ) <= 0 );
  783. }
  784. BOOL VT_LPWSTR_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  785. {
  786. return ( VT_LPWSTR_Compare( v1, v2 ) >= 0 );
  787. }
  788. BOOL VT_LPWSTR_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  789. {
  790. return ( VT_LPWSTR_Compare( v1, v2 ) > 0 );
  791. }
  792. BOOL VT_LPWSTR_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  793. {
  794. return ( VT_LPWSTR_Compare( v1, v2 ) == 0 );
  795. }
  796. BOOL VT_LPWSTR_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  797. {
  798. return ( VT_LPWSTR_Compare( v1, v2 ) != 0 );
  799. }
  800. //
  801. // VT_BLOB
  802. //
  803. int VT_BLOB_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  804. {
  805. ULONG len = v1.blob.cbSize;
  806. if ( v2.blob.cbSize < len )
  807. len = v2.blob.cbSize;
  808. int iCmp = memcmp( v1.blob.pBlobData,
  809. v2.blob.pBlobData,
  810. len );
  811. if ( iCmp != 0 || v1.blob.cbSize == v2.blob.cbSize )
  812. return( iCmp );
  813. if ( v1.blob.cbSize > v2.blob.cbSize )
  814. return( 1 );
  815. else
  816. return( -1 );
  817. }
  818. BOOL VT_BLOB_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  819. {
  820. return( VT_BLOB_Compare( v1, v2 ) < 0 );
  821. }
  822. BOOL VT_BLOB_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  823. {
  824. return( VT_BLOB_Compare( v1, v2 ) <= 0 );
  825. }
  826. BOOL VT_BLOB_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  827. {
  828. return( VT_BLOB_Compare( v1, v2 ) >= 0 );
  829. }
  830. BOOL VT_BLOB_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  831. {
  832. return( VT_BLOB_Compare( v1, v2 ) > 0 );
  833. }
  834. BOOL VT_BLOB_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  835. {
  836. return( v1.blob.cbSize == v2.blob.cbSize &&
  837. memcmp( v1.blob.pBlobData,
  838. v2.blob.pBlobData,
  839. v1.blob.cbSize ) == 0 );
  840. }
  841. BOOL VT_BLOB_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  842. {
  843. return( v1.blob.cbSize != v2.blob.cbSize ||
  844. memcmp( v1.blob.pBlobData,
  845. v2.blob.pBlobData,
  846. v1.blob.cbSize ) != 0 );
  847. }
  848. //
  849. // VT_CF
  850. //
  851. int VT_CF_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  852. {
  853. if ( v1.pclipdata->ulClipFmt != v2.pclipdata->ulClipFmt )
  854. {
  855. return( v1.pclipdata->ulClipFmt - v2.pclipdata->ulClipFmt );
  856. }
  857. ULONG len = CBPCLIPDATA(*v1.pclipdata);
  858. if ( CBPCLIPDATA(*v2.pclipdata) < len )
  859. len = CBPCLIPDATA(*v2.pclipdata);
  860. int iCmp = memcmp( v1.pclipdata->pClipData,
  861. v2.pclipdata->pClipData,
  862. len );
  863. if ( iCmp != 0 || v1.pclipdata->cbSize == v2.pclipdata->cbSize )
  864. return( iCmp );
  865. if ( v1.pclipdata->cbSize > v2.pclipdata->cbSize )
  866. return( 1 );
  867. else
  868. return( -1 );
  869. }
  870. BOOL VT_CF_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  871. {
  872. return( VT_CF_Compare( v1, v2 ) < 0 );
  873. }
  874. BOOL VT_CF_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  875. {
  876. return( VT_CF_Compare( v1, v2 ) <= 0 );
  877. }
  878. BOOL VT_CF_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  879. {
  880. return( VT_CF_Compare( v1, v2 ) >= 0 );
  881. }
  882. BOOL VT_CF_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  883. {
  884. return( VT_CF_Compare( v1, v2 ) > 0 );
  885. }
  886. BOOL VT_CF_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  887. {
  888. return( v1.pclipdata->ulClipFmt == v2.pclipdata->ulClipFmt &&
  889. v1.pclipdata->cbSize == v2.pclipdata->cbSize &&
  890. memcmp( v1.pclipdata->pClipData,
  891. v2.pclipdata->pClipData,
  892. CBPCLIPDATA(*v1.pclipdata) ) == 0 );
  893. }
  894. BOOL VT_CF_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  895. {
  896. return( v1.pclipdata->ulClipFmt != v2.pclipdata->ulClipFmt ||
  897. v1.pclipdata->cbSize != v2.pclipdata->cbSize ||
  898. memcmp( v1.pclipdata->pClipData,
  899. v2.pclipdata->pClipData,
  900. CBPCLIPDATA(*v1.pclipdata) ) != 0 );
  901. }
  902. //
  903. // VT_CLSID
  904. //
  905. int VT_CLSID_Compare( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  906. {
  907. return( memcmp( v1.puuid, v2.puuid, sizeof(GUID) ) );
  908. }
  909. BOOL VT_CLSID_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  910. {
  911. return( memcmp( v1.puuid, v2.puuid, sizeof(GUID) ) == 0 );
  912. }
  913. BOOL VT_CLSID_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  914. {
  915. return( memcmp( v1.puuid, v2.puuid, sizeof(GUID) ) != 0 );
  916. }
  917. /////////////////////////////////////////////////////////////////////////
  918. /////////////////////////////////////////////////////////////////////////
  919. /////////////////////////////////////////////////////////////////////////
  920. /////////////////////////////////////////////////////////////////////////
  921. /////////////////////////////////////////////////////////////////////////
  922. /////////////////////////////////////////////////////////////////////////
  923. //
  924. // VTP_EMPTY
  925. //
  926. int VTP_EMPTY_Compare( BYTE const *pv1, BYTE const *pv2 )
  927. {
  928. return( TRUE );
  929. }
  930. BOOL VTP_EMPTY_EQ( BYTE const *pv1, BYTE const *pv2 )
  931. {
  932. return( TRUE );
  933. }
  934. BOOL VTP_EMPTY_NE( BYTE const *pv1, BYTE const *pv2 )
  935. {
  936. return( FALSE );
  937. }
  938. //
  939. // VTP_NULL
  940. //
  941. int VTP_NULL_Compare( BYTE const *pv1, BYTE const *pv2 )
  942. {
  943. return( TRUE );
  944. }
  945. BOOL VTP_NULL_EQ( BYTE const *pv1, BYTE const *pv2 )
  946. {
  947. return( TRUE );
  948. }
  949. BOOL VTP_NULL_NE( BYTE const *pv1, BYTE const *pv2 )
  950. {
  951. return( FALSE );
  952. }
  953. //
  954. // VTP_I2
  955. //
  956. int VTP_I2_Compare( BYTE const *pv1, BYTE const *pv2 )
  957. {
  958. return( (* (short *) pv1) - (* (short *) pv2) );
  959. }
  960. BOOL VTP_I2_LT( BYTE const *pv1, BYTE const *pv2 )
  961. {
  962. return( (* (short *) pv1) < (* (short *) pv2) );
  963. }
  964. BOOL VTP_I2_LE( BYTE const *pv1, BYTE const *pv2 )
  965. {
  966. return( (* (short *) pv1) <= (* (short *) pv2) );
  967. }
  968. BOOL VTP_I2_GE( BYTE const *pv1, BYTE const *pv2 )
  969. {
  970. return( (* (short *) pv1) >= (* (short *) pv2) );
  971. }
  972. BOOL VTP_I2_GT( BYTE const *pv1, BYTE const *pv2 )
  973. {
  974. return( (* (short *) pv1) > (* (short *) pv2) );
  975. }
  976. BOOL VTP_I2_EQ( BYTE const *pv1, BYTE const *pv2 )
  977. {
  978. return( (* (short *) pv1) == (* (short *) pv2) );
  979. }
  980. BOOL VTP_I2_NE( BYTE const *pv1, BYTE const *pv2 )
  981. {
  982. return( (* (short *) pv1) != (* (short *) pv2) );
  983. }
  984. BOOL VTP_I2_AllBits( BYTE const *pv1, BYTE const *pv2 )
  985. {
  986. return( ((* (short *) pv1) & (* (short *) pv2)) == (* (short *) pv2) );
  987. }
  988. BOOL VTP_I2_SomeBits( BYTE const *pv1, BYTE const *pv2 )
  989. {
  990. return( ((* (short *) pv1) & (* (short *) pv2)) != 0 );
  991. }
  992. //
  993. // VTP_I4
  994. //
  995. int VTP_I4_Compare( BYTE const *pv1, BYTE const *pv2 )
  996. {
  997. long l1 = * (long *) pv1;
  998. long l2 = * (long *) pv2;
  999. return ( l1 > l2 ) ? 1 : ( l1 < l2 ) ? -1 : 0;
  1000. }
  1001. BOOL VTP_I4_LT( BYTE const *pv1, BYTE const *pv2 )
  1002. {
  1003. return( (* (long *) pv1) < (* (long *) pv2) );
  1004. }
  1005. BOOL VTP_I4_LE( BYTE const *pv1, BYTE const *pv2 )
  1006. {
  1007. return( (* (long *) pv1) <= (* (long *) pv2) );
  1008. }
  1009. BOOL VTP_I4_GE( BYTE const *pv1, BYTE const *pv2 )
  1010. {
  1011. return( (* (long *) pv1) >= (* (long *) pv2) );
  1012. }
  1013. BOOL VTP_I4_GT( BYTE const *pv1, BYTE const *pv2 )
  1014. {
  1015. return( (* (long *) pv1) > (* (long *) pv2) );
  1016. }
  1017. BOOL VTP_I4_EQ( BYTE const *pv1, BYTE const *pv2 )
  1018. {
  1019. return( (* (long *) pv1) == (* (long *) pv2) );
  1020. }
  1021. BOOL VTP_I4_NE( BYTE const *pv1, BYTE const *pv2 )
  1022. {
  1023. return( (* (long *) pv1) != (* (long *) pv2) );
  1024. }
  1025. BOOL VTP_I4_AllBits( BYTE const *pv1, BYTE const *pv2 )
  1026. {
  1027. return( ((* (long *) pv1) & (* (long *) pv2)) == (* (long *) pv2) );
  1028. }
  1029. BOOL VTP_I4_SomeBits( BYTE const *pv1, BYTE const *pv2 )
  1030. {
  1031. return( ((* (long *) pv1) & (* (long *) pv2)) != 0 );
  1032. }
  1033. //
  1034. // VTP_R4
  1035. //
  1036. //
  1037. // We can't use floating point in the kernel. Luckily, it's easy to
  1038. // fake comparisons on floating point. The format of an IEEE floating
  1039. // point number is:
  1040. //
  1041. // <sign bit> <biased exponent> <normalized mantissa>
  1042. //
  1043. // Because the exponent is biased, after flipping the sign bit we can
  1044. // make all comparisons as if the numbers were unsigned long.
  1045. //
  1046. int VTP_R4_Compare( BYTE const *pv1, BYTE const *pv2 )
  1047. {
  1048. #if 0
  1049. ULONG ul1 = * (ULONG *) pv1;
  1050. ULONG ul2 = * (ULONG *) pv2;
  1051. ULONG u1 = ul1 ^ R4_SignBit;
  1052. ULONG u2 = ul2 ^ R4_SignBit;
  1053. if ( (ul1 & ul2 & R4_SignBit) != 0 )
  1054. return ( ( u1 > u2 ) ? -1 : ( u1 < u2 ) ? 1 : 0 );
  1055. else
  1056. return ( ( u1 > u2 ) ? 1 : ( u1 < u2 ) ? -1 : 0 );
  1057. #else // 0
  1058. float f1 = * (float *) pv1;
  1059. float f2 = * (float *) pv2;
  1060. return ( f1 > f2 ) ? 1 : ( f1 < f2 ) ? -1 : 0;
  1061. #endif // 0
  1062. }
  1063. BOOL VTP_R4_LT( BYTE const *pv1, BYTE const *pv2 )
  1064. {
  1065. return VTP_R4_Compare( pv1, pv2 ) < 0;
  1066. }
  1067. BOOL VTP_R4_LE( BYTE const *pv1, BYTE const *pv2 )
  1068. {
  1069. return VTP_R4_Compare( pv1, pv2 ) <= 0;
  1070. }
  1071. BOOL VTP_R4_GE( BYTE const *pv1, BYTE const *pv2 )
  1072. {
  1073. return VTP_R4_Compare( pv1, pv2 ) >= 0;
  1074. }
  1075. BOOL VTP_R4_GT( BYTE const *pv1, BYTE const *pv2 )
  1076. {
  1077. return VTP_R4_Compare( pv1, pv2 ) > 0;
  1078. }
  1079. BOOL VTP_R4_EQ( BYTE const *pv1, BYTE const *pv2 )
  1080. {
  1081. return VTP_R4_Compare( pv1, pv2 ) == 0;
  1082. }
  1083. BOOL VTP_R4_NE( BYTE const *pv1, BYTE const *pv2 )
  1084. {
  1085. return VTP_R4_Compare( pv1, pv2 ) != 0;
  1086. }
  1087. //
  1088. // VTP_R8
  1089. //
  1090. int VTP_R8_Compare( BYTE const *pv1, BYTE const *pv2 )
  1091. {
  1092. #if 0
  1093. ULONGLONG uh1 = * (ULONGLONG *) pv1;
  1094. ULONGLONG uh2 = * (ULONGLONG *) pv2;
  1095. if ( (uh1 & uh2 & R8_SignBit) != 0 )
  1096. return( (uh1 ^ R8_SignBit) < (uh2 ^ R8_SignBit) ? 1 :
  1097. (uh1 ^ R8_SignBit) == (uh2 ^ R8_SignBit) ? 0 :
  1098. -1 );
  1099. else
  1100. return( (uh1 ^ R8_SignBit) > (uh2 ^ R8_SignBit) ? 1 :
  1101. (uh1 ^ R8_SignBit) == (uh2 ^ R8_SignBit) ? 0 :
  1102. -1 );
  1103. #else // 0
  1104. double d1 = * (double *) pv1;
  1105. double d2 = * (double *) pv2;
  1106. return ( d1 > d2 ) ? 1 : ( d1 < d2 ) ? -1 : 0;
  1107. #endif // 0
  1108. }
  1109. BOOL VTP_R8_LT( BYTE const *pv1, BYTE const *pv2 )
  1110. {
  1111. return VTP_R8_Compare( pv1, pv2 ) < 0;
  1112. }
  1113. BOOL VTP_R8_LE( BYTE const *pv1, BYTE const *pv2 )
  1114. {
  1115. return VTP_R8_Compare( pv1, pv2 ) <= 0;
  1116. }
  1117. BOOL VTP_R8_GE( BYTE const *pv1, BYTE const *pv2 )
  1118. {
  1119. return VTP_R8_Compare( pv1, pv2 ) >= 0;
  1120. }
  1121. BOOL VTP_R8_GT( BYTE const *pv1, BYTE const *pv2 )
  1122. {
  1123. return VTP_R8_Compare( pv1, pv2 ) > 0;
  1124. }
  1125. BOOL VTP_R8_EQ( BYTE const *pv1, BYTE const *pv2 )
  1126. {
  1127. return VTP_R8_Compare( pv1, pv2 ) == 0;
  1128. }
  1129. BOOL VTP_R8_NE( BYTE const *pv1, BYTE const *pv2 )
  1130. {
  1131. return VTP_R8_Compare( pv1, pv2 ) != 0;
  1132. }
  1133. //
  1134. // VTP_BSTR
  1135. //
  1136. int VTP_BSTR_Compare( BYTE const *pv1, BYTE const *pv2 )
  1137. {
  1138. BSTR const pxv1 = *(BSTR*)pv1;
  1139. BSTR const pxv2 = *(BSTR*)pv2;
  1140. ULONG len = BSTRLEN(pxv1);
  1141. if ( BSTRLEN(pxv2) < len )
  1142. len = BSTRLEN(pxv2);
  1143. int iCmp = _wcsnicmp( pxv1, pxv2, len / sizeof (OLECHAR) );
  1144. if ( iCmp != 0 || BSTRLEN(pxv1) == BSTRLEN(pxv2) )
  1145. return( iCmp );
  1146. if ( BSTRLEN(pxv1) > BSTRLEN(pxv2) )
  1147. return( 1 );
  1148. else
  1149. return( -1 );
  1150. }
  1151. BOOL VTP_BSTR_LT( BYTE const *pv1, BYTE const *pv2 )
  1152. {
  1153. return( VTP_BSTR_Compare( pv1, pv2 ) < 0 );
  1154. }
  1155. BOOL VTP_BSTR_LE( BYTE const *pv1, BYTE const *pv2 )
  1156. {
  1157. return( VTP_BSTR_Compare( pv1, pv2 ) <= 0 );
  1158. }
  1159. BOOL VTP_BSTR_GE( BYTE const *pv1, BYTE const *pv2 )
  1160. {
  1161. return( VTP_BSTR_Compare( pv1, pv2 ) >= 0 );
  1162. }
  1163. BOOL VTP_BSTR_GT( BYTE const *pv1, BYTE const *pv2 )
  1164. {
  1165. return( VTP_BSTR_Compare( pv1, pv2 ) > 0 );
  1166. }
  1167. BOOL VTP_BSTR_EQ( BYTE const *pv1, BYTE const *pv2 )
  1168. {
  1169. BSTR const pxv1 = *(BSTR*)pv1;
  1170. BSTR const pxv2 = *(BSTR*)pv2;
  1171. return( BSTRLEN(pxv1) == BSTRLEN(pxv2) &&
  1172. _wcsnicmp( pxv1, pxv2, BSTRLEN(pxv1) / sizeof (OLECHAR) ) == 0 );
  1173. }
  1174. BOOL VTP_BSTR_NE( BYTE const *pv1, BYTE const *pv2 )
  1175. {
  1176. BSTR const pxv1 = *(BSTR*)pv1;
  1177. BSTR const pxv2 = *(BSTR*)pv2;
  1178. return( BSTRLEN(pxv1) != BSTRLEN(pxv2) ||
  1179. _wcsnicmp( pxv1, pxv2, BSTRLEN(pxv1) / sizeof (OLECHAR) ) != 0 );
  1180. }
  1181. //
  1182. // VTP_BOOL
  1183. //
  1184. int VTP_BOOL_Compare( BYTE const *pv1, BYTE const *pv2 )
  1185. {
  1186. if ((*(VARIANT_BOOL *) pv1) == 0)
  1187. if ((*(VARIANT_BOOL *) pv2) == 0)
  1188. return( 0 );
  1189. else
  1190. return( -1 );
  1191. else
  1192. if ((*(VARIANT_BOOL *) pv2) == 0)
  1193. return( 1 );
  1194. else
  1195. return( 0 );
  1196. }
  1197. BOOL VTP_BOOL_EQ( BYTE const *pv1, BYTE const *pv2 )
  1198. {
  1199. return( ( ((*(VARIANT_BOOL *) pv1)==0) && ((*(VARIANT_BOOL *) pv2)==0) ) ||
  1200. ( ((*(VARIANT_BOOL *) pv1)!=0) && ((*(VARIANT_BOOL *) pv2)!=0) ) );
  1201. }
  1202. BOOL VTP_BOOL_NE( BYTE const *pv1, BYTE const *pv2 )
  1203. {
  1204. return( !VTP_BOOL_EQ( pv1, pv2 ) );
  1205. }
  1206. //
  1207. // VTP_VARIANT
  1208. //
  1209. int VTP_VARIANT_Compare( BYTE const *pv1, BYTE const *pv2 )
  1210. {
  1211. return VT_VARIANT_Compare( * (PROPVARIANT *) pv1, * (PROPVARIANT *) pv2 );
  1212. }
  1213. BOOL VTP_VARIANT_LT( BYTE const *pv1, BYTE const *pv2 )
  1214. {
  1215. return VT_VARIANT_LT( * (PROPVARIANT *) pv1, * (PROPVARIANT *) pv2 );
  1216. }
  1217. BOOL VTP_VARIANT_LE( BYTE const *pv1, BYTE const *pv2 )
  1218. {
  1219. return VT_VARIANT_LE( * (PROPVARIANT *) pv1, * (PROPVARIANT *) pv2 );
  1220. }
  1221. BOOL VTP_VARIANT_GE( BYTE const *pv1, BYTE const *pv2 )
  1222. {
  1223. return VT_VARIANT_GE( * (PROPVARIANT *) pv1, * (PROPVARIANT *) pv2 );
  1224. }
  1225. BOOL VTP_VARIANT_GT( BYTE const *pv1, BYTE const *pv2 )
  1226. {
  1227. return VT_VARIANT_GT( * (PROPVARIANT *) pv1, * (PROPVARIANT *) pv2 );
  1228. }
  1229. BOOL VTP_VARIANT_EQ( BYTE const *pv1, BYTE const *pv2 )
  1230. {
  1231. return VT_VARIANT_EQ( * (PROPVARIANT *) pv1, * (PROPVARIANT *) pv2 );
  1232. }
  1233. BOOL VTP_VARIANT_NE( BYTE const *pv1, BYTE const *pv2 )
  1234. {
  1235. return VT_VARIANT_NE( * (PROPVARIANT *) pv1, * (PROPVARIANT *) pv2 );
  1236. }
  1237. //
  1238. // VTP_DECIMAL
  1239. //
  1240. int VTP_DEC_Compare( BYTE const *pv1, BYTE const *pv2 )
  1241. {
  1242. PROPVARIANT v1;
  1243. RtlCopyMemory( &v1, pv1, sizeof DECIMAL );
  1244. v1.vt = VT_DECIMAL;
  1245. PROPVARIANT v2;
  1246. RtlCopyMemory( &v2, pv2, sizeof DECIMAL );
  1247. v2.vt = VT_DECIMAL;
  1248. return VT_DEC_Compare( v1, v2 );
  1249. }
  1250. BOOL VTP_DEC_LT( BYTE const *pv1, BYTE const *pv2 )
  1251. {
  1252. return ( VTP_DEC_Compare( pv1, pv2 ) < 0 );
  1253. }
  1254. BOOL VTP_DEC_LE( BYTE const *pv1, BYTE const *pv2 )
  1255. {
  1256. return ( VTP_DEC_Compare( pv1, pv2 ) <= 0 );
  1257. }
  1258. BOOL VTP_DEC_GE( BYTE const *pv1, BYTE const *pv2 )
  1259. {
  1260. return ( VTP_DEC_Compare( pv1, pv2 ) >= 0 );
  1261. }
  1262. BOOL VTP_DEC_GT( BYTE const *pv1, BYTE const *pv2 )
  1263. {
  1264. return ( VTP_DEC_Compare( pv1, pv2 ) > 0 );
  1265. }
  1266. BOOL VTP_DEC_EQ( BYTE const *pv1, BYTE const *pv2 )
  1267. {
  1268. return ( VTP_DEC_Compare( pv1, pv2 ) == 0 );
  1269. }
  1270. BOOL VTP_DEC_NE( BYTE const *pv1, BYTE const *pv2 )
  1271. {
  1272. return ( VTP_DEC_Compare( pv1, pv2 ) != 0 );
  1273. }
  1274. //
  1275. // VTP_I1
  1276. //
  1277. int VTP_I1_Compare( BYTE const *pv1, BYTE const *pv2 )
  1278. {
  1279. return( (*(signed char *) pv1) - (*(signed char *) pv2) );
  1280. }
  1281. BOOL VTP_I1_LT( BYTE const *pv1, BYTE const *pv2 )
  1282. {
  1283. return( (*(signed char *) pv1) < (*(signed char *) pv2) );
  1284. }
  1285. BOOL VTP_I1_LE( BYTE const *pv1, BYTE const *pv2 )
  1286. {
  1287. return( (*(signed char *) pv1) <= (*(signed char *) pv2) );
  1288. }
  1289. BOOL VTP_I1_GE( BYTE const *pv1, BYTE const *pv2 )
  1290. {
  1291. return( (*(signed char *) pv1) >= (*(signed char *) pv2) );
  1292. }
  1293. BOOL VTP_I1_GT( BYTE const *pv1, BYTE const *pv2 )
  1294. {
  1295. return( (*(signed char *) pv1) > (*(signed char *) pv2) );
  1296. }
  1297. BOOL VTP_I1_EQ( BYTE const *pv1, BYTE const *pv2 )
  1298. {
  1299. return( (*(signed char *) pv1) == (*(signed char *) pv2) );
  1300. }
  1301. BOOL VTP_I1_NE( BYTE const *pv1, BYTE const *pv2 )
  1302. {
  1303. return( (*(signed char *) pv1) != (*(signed char *) pv2) );
  1304. }
  1305. BOOL VTP_I1_AllBits( BYTE const *pv1, BYTE const *pv2 )
  1306. {
  1307. return( ((*(signed char *) pv1) & (*(signed char *) pv2)) == (*(signed char *) pv2) );
  1308. }
  1309. BOOL VTP_I1_SomeBits( BYTE const *pv1, BYTE const *pv2 )
  1310. {
  1311. return( ((*(signed char *) pv1) & (*(signed char *) pv2)) != 0 );
  1312. }
  1313. //
  1314. // VTP_UI1
  1315. //
  1316. int VTP_UI1_Compare( BYTE const *pv1, BYTE const *pv2 )
  1317. {
  1318. return( (*(unsigned char *) pv1) - (*(unsigned char *) pv2) );
  1319. }
  1320. BOOL VTP_UI1_LT( BYTE const *pv1, BYTE const *pv2 )
  1321. {
  1322. return( (*(unsigned char *) pv1) < (*(unsigned char *) pv2) );
  1323. }
  1324. BOOL VTP_UI1_LE( BYTE const *pv1, BYTE const *pv2 )
  1325. {
  1326. return( (*(unsigned char *) pv1) <= (*(unsigned char *) pv2) );
  1327. }
  1328. BOOL VTP_UI1_GE( BYTE const *pv1, BYTE const *pv2 )
  1329. {
  1330. return( (*(unsigned char *) pv1) >= (*(unsigned char *) pv2) );
  1331. }
  1332. BOOL VTP_UI1_GT( BYTE const *pv1, BYTE const *pv2 )
  1333. {
  1334. return( (*(unsigned char *) pv1) > (*(unsigned char *) pv2) );
  1335. }
  1336. BOOL VTP_UI1_EQ( BYTE const *pv1, BYTE const *pv2 )
  1337. {
  1338. return( (*(unsigned char *) pv1) == (*(unsigned char *) pv2) );
  1339. }
  1340. BOOL VTP_UI1_NE( BYTE const *pv1, BYTE const *pv2 )
  1341. {
  1342. return( (*(unsigned char *) pv1) != (*(unsigned char *) pv2) );
  1343. }
  1344. BOOL VTP_UI1_AllBits( BYTE const *pv1, BYTE const *pv2 )
  1345. {
  1346. return( ((*(unsigned char *) pv1) & (*(unsigned char *) pv2)) == (*(unsigned char *) pv2) );
  1347. }
  1348. BOOL VTP_UI1_SomeBits( BYTE const *pv1, BYTE const *pv2 )
  1349. {
  1350. return( ((*(unsigned char *) pv1) & (*(unsigned char *) pv2)) != 0 );
  1351. }
  1352. //
  1353. // VTP_UI2
  1354. //
  1355. int VTP_UI2_Compare( BYTE const *pv1, BYTE const *pv2 )
  1356. {
  1357. return( (*(USHORT *) pv1) - (*(USHORT *) pv2) );
  1358. }
  1359. BOOL VTP_UI2_LT( BYTE const *pv1, BYTE const *pv2 )
  1360. {
  1361. return( (*(USHORT *) pv1) < (*(USHORT *) pv2) );
  1362. }
  1363. BOOL VTP_UI2_LE( BYTE const *pv1, BYTE const *pv2 )
  1364. {
  1365. return( (*(USHORT *) pv1) <= (*(USHORT *) pv2) );
  1366. }
  1367. BOOL VTP_UI2_GE( BYTE const *pv1, BYTE const *pv2 )
  1368. {
  1369. return( (*(USHORT *) pv1) >= (*(USHORT *) pv2) );
  1370. }
  1371. BOOL VTP_UI2_GT( BYTE const *pv1, BYTE const *pv2 )
  1372. {
  1373. return( (*(USHORT *) pv1) > (*(USHORT *) pv2) );
  1374. }
  1375. BOOL VTP_UI2_EQ( BYTE const *pv1, BYTE const *pv2 )
  1376. {
  1377. return( (*(USHORT *) pv1) == (*(USHORT *) pv2) );
  1378. }
  1379. BOOL VTP_UI2_NE( BYTE const *pv1, BYTE const *pv2 )
  1380. {
  1381. return( (*(USHORT *) pv1) != (*(USHORT *) pv2) );
  1382. }
  1383. BOOL VTP_UI2_AllBits( BYTE const *pv1, BYTE const *pv2 )
  1384. {
  1385. return( ((*(USHORT *) pv1) & (*(USHORT *) pv2)) == (*(USHORT *) pv2) );
  1386. }
  1387. BOOL VTP_UI2_SomeBits( BYTE const *pv1, BYTE const *pv2 )
  1388. {
  1389. return( ((*(USHORT *) pv1) & (*(USHORT *) pv2)) != 0 );
  1390. }
  1391. //
  1392. // VTP_UI4
  1393. //
  1394. int VTP_UI4_Compare( BYTE const *pv1, BYTE const *pv2 )
  1395. {
  1396. ULONG ul1 = * (ULONG *) pv1;
  1397. ULONG ul2 = * (ULONG *) pv2;
  1398. return ( ul1 > ul2 ) ? 1 : ( ul1 < ul2 ) ? -1 : 0;
  1399. }
  1400. BOOL VTP_UI4_LT( BYTE const *pv1, BYTE const *pv2 )
  1401. {
  1402. return( (*(ULONG *) pv1) < (*(ULONG *) pv2) );
  1403. }
  1404. BOOL VTP_UI4_LE( BYTE const *pv1, BYTE const *pv2 )
  1405. {
  1406. return( (*(ULONG *) pv1) <= (*(ULONG *) pv2) );
  1407. }
  1408. BOOL VTP_UI4_GE( BYTE const *pv1, BYTE const *pv2 )
  1409. {
  1410. return( (*(ULONG *) pv1) >= (*(ULONG *) pv2) );
  1411. }
  1412. BOOL VTP_UI4_GT( BYTE const *pv1, BYTE const *pv2 )
  1413. {
  1414. return( (*(ULONG *) pv1) > (*(ULONG *) pv2) );
  1415. }
  1416. BOOL VTP_UI4_EQ( BYTE const *pv1, BYTE const *pv2 )
  1417. {
  1418. return( (*(ULONG *) pv1) == (*(ULONG *) pv2) );
  1419. }
  1420. BOOL VTP_UI4_NE( BYTE const *pv1, BYTE const *pv2 )
  1421. {
  1422. return( (*(ULONG *) pv1) != (*(ULONG *) pv2) );
  1423. }
  1424. BOOL VTP_UI4_AllBits( BYTE const *pv1, BYTE const *pv2 )
  1425. {
  1426. return( ((*(ULONG *) pv1) & (*(ULONG *) pv2)) == (*(ULONG *) pv2) );
  1427. }
  1428. BOOL VTP_UI4_SomeBits( BYTE const *pv1, BYTE const *pv2 )
  1429. {
  1430. return( ((*(ULONG *) pv1) & (*(ULONG *) pv2)) != 0 );
  1431. }
  1432. //
  1433. // VTP_I8
  1434. //
  1435. int VTP_I8_Compare( BYTE const *pv1, BYTE const *pv2 )
  1436. {
  1437. return( (*(LONGLONG *) pv1) > (*(LONGLONG *) pv2) ? 1 :
  1438. (*(LONGLONG *) pv1) == (*(LONGLONG *) pv2) ? 0 :
  1439. -1 );
  1440. }
  1441. BOOL VTP_I8_LT( BYTE const *pv1, BYTE const *pv2 )
  1442. {
  1443. return( (*(LONGLONG *) pv1) < (*(LONGLONG *) pv2) );
  1444. }
  1445. BOOL VTP_I8_LE( BYTE const *pv1, BYTE const *pv2 )
  1446. {
  1447. return( (*(LONGLONG *) pv1) <= (*(LONGLONG *) pv2) );
  1448. }
  1449. BOOL VTP_I8_GE( BYTE const *pv1, BYTE const *pv2 )
  1450. {
  1451. return( (*(LONGLONG *) pv1) >= (*(LONGLONG *) pv2) );
  1452. }
  1453. BOOL VTP_I8_GT( BYTE const *pv1, BYTE const *pv2 )
  1454. {
  1455. return( (*(LONGLONG *) pv1) > (*(LONGLONG *) pv2) );
  1456. }
  1457. BOOL VTP_I8_EQ( BYTE const *pv1, BYTE const *pv2 )
  1458. {
  1459. return( (*(LONGLONG *) pv1) == (*(LONGLONG *) pv2) );
  1460. }
  1461. BOOL VTP_I8_NE( BYTE const *pv1, BYTE const *pv2 )
  1462. {
  1463. return( (*(LONGLONG *) pv1) != (*(LONGLONG *) pv2) );
  1464. }
  1465. BOOL VTP_I8_AllBits( BYTE const *pv1, BYTE const *pv2 )
  1466. {
  1467. return( ((*(LONGLONG *) pv1) & (*(LONGLONG *) pv2)) == (*(LONGLONG *) pv2) );
  1468. }
  1469. BOOL VTP_I8_SomeBits( BYTE const *pv1, BYTE const *pv2 )
  1470. {
  1471. return( ((*(LONGLONG *) pv1) & (*(LONGLONG *) pv2)) != 0 );
  1472. }
  1473. //
  1474. // VTP_UI8
  1475. //
  1476. int VTP_UI8_Compare( BYTE const *pv1, BYTE const *pv2 )
  1477. {
  1478. return( (*(ULONGLONG *) pv1) > (*(ULONGLONG *) pv2) ? 1 :
  1479. (*(ULONGLONG *) pv1) == (*(ULONGLONG *) pv2) ? 0 :
  1480. -1 );
  1481. }
  1482. BOOL VTP_UI8_LT( BYTE const *pv1, BYTE const *pv2 )
  1483. {
  1484. return( (*(ULONGLONG *) pv1) < (*(ULONGLONG *) pv2) );
  1485. }
  1486. BOOL VTP_UI8_LE( BYTE const *pv1, BYTE const *pv2 )
  1487. {
  1488. return( (*(ULONGLONG *) pv1) <= (*(ULONGLONG *) pv2) );
  1489. }
  1490. BOOL VTP_UI8_GE( BYTE const *pv1, BYTE const *pv2 )
  1491. {
  1492. return( (*(ULONGLONG *) pv1) >= (*(ULONGLONG *) pv2) );
  1493. }
  1494. BOOL VTP_UI8_GT( BYTE const *pv1, BYTE const *pv2 )
  1495. {
  1496. return( (*(ULONGLONG *) pv1) > (*(ULONGLONG *) pv2) );
  1497. }
  1498. BOOL VTP_UI8_EQ( BYTE const *pv1, BYTE const *pv2 )
  1499. {
  1500. return( (*(ULONGLONG *) pv1) == (*(ULONGLONG *) pv2) );
  1501. }
  1502. BOOL VTP_UI8_NE( BYTE const *pv1, BYTE const *pv2 )
  1503. {
  1504. return( (*(ULONGLONG *) pv1) != (*(ULONGLONG *) pv2) );
  1505. }
  1506. BOOL VTP_UI8_AllBits( BYTE const *pv1, BYTE const *pv2 )
  1507. {
  1508. return( ((*(ULONGLONG *) pv1) & (*(ULONGLONG *) pv2)) == (*(ULONGLONG *) pv2) );
  1509. }
  1510. BOOL VTP_UI8_SomeBits( BYTE const *pv1, BYTE const *pv2 )
  1511. {
  1512. return( ((*(ULONGLONG *) pv1) & (*(ULONGLONG *) pv2)) != 0 );
  1513. }
  1514. //
  1515. // VTP_LPSTR
  1516. //
  1517. int VTP_LPSTR_Compare( BYTE const *pv1, BYTE const *pv2 )
  1518. {
  1519. return ( _stricmp( (*(char **) pv1), (*(char **) pv2) ) );
  1520. }
  1521. BOOL VTP_LPSTR_LT( BYTE const *pv1, BYTE const *pv2 )
  1522. {
  1523. int rc = _stricmp( (*(char **) pv1), (*(char **) pv2) );
  1524. return( rc < 0 );
  1525. }
  1526. BOOL VTP_LPSTR_LE( BYTE const *pv1, BYTE const *pv2 )
  1527. {
  1528. int rc = _stricmp( (*(char **) pv1), (*(char **) pv2) );
  1529. return( rc <= 0 );
  1530. }
  1531. BOOL VTP_LPSTR_GE( BYTE const *pv1, BYTE const *pv2 )
  1532. {
  1533. int rc = _stricmp( (*(char **) pv1), (*(char **) pv2) );
  1534. return( rc >= 0 );
  1535. }
  1536. BOOL VTP_LPSTR_GT( BYTE const *pv1, BYTE const *pv2 )
  1537. {
  1538. int rc = _stricmp( (*(char **) pv1), (*(char **) pv2) );
  1539. return( rc > 0 );
  1540. }
  1541. BOOL VTP_LPSTR_EQ( BYTE const *pv1, BYTE const *pv2 )
  1542. {
  1543. return( _stricmp( (*(char **) pv1), (*(char **) pv2) ) == 0 );
  1544. }
  1545. BOOL VTP_LPSTR_NE( BYTE const *pv1, BYTE const *pv2 )
  1546. {
  1547. return( _stricmp( (*(char **) pv1), (*(char **) pv2) ) != 0 );
  1548. }
  1549. //
  1550. // VTP_LPWSTR
  1551. //
  1552. int VTP_LPWSTR_Compare( BYTE const *pv1, BYTE const *pv2 )
  1553. {
  1554. int rc = CompareStringW( LOCALE_SYSTEM_DEFAULT,
  1555. NORM_IGNORECASE,
  1556. (*(WCHAR **) pv1),
  1557. -1,
  1558. (*(WCHAR **) pv2),
  1559. -1 );
  1560. //
  1561. // rc == 1, means less than
  1562. // rc == 2, means equal
  1563. // rc == 3, means greater than
  1564. //
  1565. return rc - 2;
  1566. }
  1567. BOOL VTP_LPWSTR_LT( BYTE const *pv1, BYTE const *pv2 )
  1568. {
  1569. return ( VTP_LPWSTR_Compare( pv1, pv2 ) < 0 );
  1570. }
  1571. BOOL VTP_LPWSTR_LE( BYTE const *pv1, BYTE const *pv2 )
  1572. {
  1573. return ( VTP_LPWSTR_Compare( pv1, pv2 ) <= 0 );
  1574. }
  1575. BOOL VTP_LPWSTR_GE( BYTE const *pv1, BYTE const *pv2 )
  1576. {
  1577. return ( VTP_LPWSTR_Compare( pv1, pv2 ) >= 0 );
  1578. }
  1579. BOOL VTP_LPWSTR_GT( BYTE const *pv1, BYTE const *pv2 )
  1580. {
  1581. return ( VTP_LPWSTR_Compare( pv1, pv2 ) > 0 );
  1582. }
  1583. BOOL VTP_LPWSTR_EQ( BYTE const *pv1, BYTE const *pv2 )
  1584. {
  1585. return ( VTP_LPWSTR_Compare( pv1, pv2 ) == 0 );
  1586. }
  1587. BOOL VTP_LPWSTR_NE( BYTE const *pv1, BYTE const *pv2 )
  1588. {
  1589. return ( VTP_LPWSTR_Compare( pv1, pv2 ) != 0 );
  1590. }
  1591. //
  1592. // VTP_BLOB
  1593. //
  1594. int VTP_BLOB_Compare( BYTE const *pv1, BYTE const *pv2 )
  1595. {
  1596. ULONG len = (*(BLOB **) pv1)->cbSize;
  1597. if ( (*(BLOB **) pv2)->cbSize < len )
  1598. len = (*(BLOB **) pv2)->cbSize;
  1599. int iCmp = memcmp( (*(BLOB **) pv1)->pBlobData,
  1600. (*(BLOB **) pv2)->pBlobData,
  1601. len );
  1602. if ( iCmp != 0 || (*(BLOB **) pv1)->cbSize == (*(BLOB **) pv2)->cbSize )
  1603. return( iCmp );
  1604. if ( (*(BLOB **) pv1)->cbSize > (*(BLOB **) pv2)->cbSize )
  1605. return( 1 );
  1606. else
  1607. return( -1 );
  1608. }
  1609. BOOL VTP_BLOB_LT( BYTE const *pv1, BYTE const *pv2 )
  1610. {
  1611. return( VTP_BLOB_Compare( pv1, pv2 ) < 0 );
  1612. }
  1613. BOOL VTP_BLOB_LE( BYTE const *pv1, BYTE const *pv2 )
  1614. {
  1615. return( VTP_BLOB_Compare( pv1, pv2 ) <= 0 );
  1616. }
  1617. BOOL VTP_BLOB_GE( BYTE const *pv1, BYTE const *pv2 )
  1618. {
  1619. return( VTP_BLOB_Compare( pv1, pv2 ) >= 0 );
  1620. }
  1621. BOOL VTP_BLOB_GT( BYTE const *pv1, BYTE const *pv2 )
  1622. {
  1623. return( VTP_BLOB_Compare( pv1, pv2 ) > 0 );
  1624. }
  1625. BOOL VTP_BLOB_EQ( BYTE const *pv1, BYTE const *pv2 )
  1626. {
  1627. return( (*(BLOB **) pv1)->cbSize == (*(BLOB **) pv2)->cbSize &&
  1628. memcmp( (*(BLOB **) pv1)->pBlobData,
  1629. (*(BLOB **) pv2)->pBlobData,
  1630. (*(BLOB **) pv1)->cbSize ) == 0 );
  1631. }
  1632. BOOL VTP_BLOB_NE( BYTE const *pv1, BYTE const *pv2 )
  1633. {
  1634. return( (*(BLOB **) pv1)->cbSize != (*(BLOB **) pv2)->cbSize ||
  1635. memcmp( (*(BLOB **) pv1)->pBlobData,
  1636. (*(BLOB **) pv2)->pBlobData,
  1637. (*(BLOB **) pv1)->cbSize ) != 0 );
  1638. }
  1639. //
  1640. // VTP_CF
  1641. //
  1642. int VTP_CF_Compare( BYTE const *pv1, BYTE const *pv2 )
  1643. {
  1644. if ( (* (CLIPDATA **) pv1)->ulClipFmt != (* (CLIPDATA **) pv2)->ulClipFmt )
  1645. {
  1646. return( (* (CLIPDATA **) pv1)->ulClipFmt - (* (CLIPDATA **) pv2)->ulClipFmt );
  1647. }
  1648. ULONG len = CBPCLIPDATA( **(CLIPDATA **) pv1 );
  1649. if ( CBPCLIPDATA( **(CLIPDATA **) pv2 ) < len )
  1650. len = CBPCLIPDATA( **(CLIPDATA **) pv2 );
  1651. int iCmp = memcmp( (* (CLIPDATA **) pv1)->pClipData,
  1652. (* (CLIPDATA **) pv2)->pClipData,
  1653. len );
  1654. if ( iCmp != 0 || (* (CLIPDATA **) pv1)->cbSize == (* (CLIPDATA **) pv2)->cbSize)
  1655. return( iCmp );
  1656. if ( (* (CLIPDATA **) pv1)->cbSize > (* (CLIPDATA **) pv2)->cbSize )
  1657. return( 1 );
  1658. else
  1659. return( -1 );
  1660. }
  1661. BOOL VTP_CF_LT( BYTE const *pv1, BYTE const *pv2 )
  1662. {
  1663. return( VTP_CF_Compare( pv1, pv2 ) < 0 );
  1664. }
  1665. BOOL VTP_CF_LE( BYTE const *pv1, BYTE const *pv2 )
  1666. {
  1667. return( VTP_CF_Compare( pv1, pv2 ) <= 0 );
  1668. }
  1669. BOOL VTP_CF_GE( BYTE const *pv1, BYTE const *pv2 )
  1670. {
  1671. return( VTP_CF_Compare( pv1, pv2 ) >= 0 );
  1672. }
  1673. BOOL VTP_CF_GT( BYTE const *pv1, BYTE const *pv2 )
  1674. {
  1675. return( VTP_CF_Compare( pv1, pv2 ) > 0 );
  1676. }
  1677. BOOL VTP_CF_EQ( BYTE const *pv1, BYTE const *pv2 )
  1678. {
  1679. return( (* (CLIPDATA **) pv1)->ulClipFmt == (* (CLIPDATA **) pv2)->ulClipFmt &&
  1680. (* (CLIPDATA **) pv1)->cbSize == (* (CLIPDATA **) pv2)->cbSize &&
  1681. memcmp( (* (CLIPDATA **) pv1)->pClipData,
  1682. (* (CLIPDATA **) pv2)->pClipData,
  1683. CBPCLIPDATA( **(CLIPDATA **) pv1 )) == 0 );
  1684. }
  1685. BOOL VTP_CF_NE( BYTE const *pv1, BYTE const *pv2 )
  1686. {
  1687. return( (* (CLIPDATA **) pv1)->ulClipFmt != (* (CLIPDATA **) pv2)->ulClipFmt &&
  1688. (* (CLIPDATA **) pv1)->cbSize != (* (CLIPDATA **) pv2)->cbSize ||
  1689. memcmp( (* (CLIPDATA **) pv1)->pClipData,
  1690. (* (CLIPDATA **) pv2)->pClipData,
  1691. CBPCLIPDATA( **(CLIPDATA **) pv1 )) != 0 );
  1692. }
  1693. //
  1694. // VTP_CLSID. V means vector ( a pointer to a guid )
  1695. // S meand singleton ( a pointer to a pointer to a guid )
  1696. //
  1697. int VTP_VV_CLSID_Compare( BYTE const *pv1, BYTE const *pv2 )
  1698. {
  1699. return( memcmp( pv1, pv2, sizeof GUID ) );
  1700. }
  1701. int VTP_VS_CLSID_Compare( BYTE const *pv1, BYTE const *pv2 )
  1702. {
  1703. return( memcmp( pv1, (* (CLSID __RPC_FAR * *) pv2), sizeof GUID ) );
  1704. }
  1705. int VTP_SV_CLSID_Compare( BYTE const *pv1, BYTE const *pv2 )
  1706. {
  1707. return( memcmp( (* (CLSID __RPC_FAR * *) pv1), pv2, sizeof GUID ) );
  1708. }
  1709. int VTP_SS_CLSID_Compare( BYTE const *pv1, BYTE const *pv2 )
  1710. {
  1711. return( memcmp( (* (CLSID __RPC_FAR * *) pv1), (* (CLSID __RPC_FAR * *) pv2), sizeof GUID ) );
  1712. }
  1713. BOOL VTP_SS_CLSID_EQ( BYTE const *pv1, BYTE const *pv2 )
  1714. {
  1715. return( memcmp( (* (CLSID __RPC_FAR * *) pv1), (* (CLSID __RPC_FAR * *) pv2), sizeof GUID ) == 0 );
  1716. }
  1717. BOOL VTP_SS_CLSID_NE( BYTE const *pv1, BYTE const *pv2 )
  1718. {
  1719. return( memcmp( (* (CLSID __RPC_FAR * *) pv1), (* (CLSID __RPC_FAR * *) pv2), sizeof GUID ) != 0 );
  1720. }
  1721. BOOL VTP_VV_CLSID_EQ( BYTE const *pv1, BYTE const *pv2 )
  1722. {
  1723. return( memcmp( pv1, pv2, sizeof GUID ) == 0 );
  1724. }
  1725. BOOL VTP_VV_CLSID_NE( BYTE const *pv1, BYTE const *pv2 )
  1726. {
  1727. return( memcmp( pv1, pv2, sizeof GUID ) != 0 );
  1728. }
  1729. BOOL VTP_VS_CLSID_EQ( BYTE const *pv1, BYTE const *pv2 )
  1730. {
  1731. return( memcmp( pv1, (* (CLSID __RPC_FAR * *) pv2), sizeof GUID ) == 0 );
  1732. }
  1733. BOOL VTP_VS_CLSID_NE( BYTE const *pv1, BYTE const *pv2 )
  1734. {
  1735. return( memcmp( pv1, (* (CLSID __RPC_FAR * *) pv2), sizeof GUID ) != 0 );
  1736. }
  1737. BOOL VTP_SV_CLSID_EQ( BYTE const *pv1, BYTE const *pv2 )
  1738. {
  1739. return( memcmp( (* (CLSID __RPC_FAR * *) pv1), pv2, sizeof GUID ) == 0 );
  1740. }
  1741. BOOL VTP_SV_CLSID_NE( BYTE const *pv1, BYTE const *pv2 )
  1742. {
  1743. return( memcmp( (* (CLSID __RPC_FAR * *) pv1), pv2, sizeof GUID ) != 0 );
  1744. }
  1745. /////////////////////////////////////////////////////////////////////////
  1746. /////////////////////////////////////////////////////////////////////////
  1747. /////////////////////////////////////////////////////////////////////////
  1748. /////////////////////////////////////////////////////////////////////////
  1749. /////////////////////////////////////////////////////////////////////////
  1750. /////////////////////////////////////////////////////////////////////////
  1751. ULONG const CComparators::_iStart = VT_EMPTY;
  1752. CComparators::SComparators const CComparators::_aVariantComparators[] = {
  1753. // VT_EMPTY
  1754. { VT_EMPTY_Compare, VTP_EMPTY_Compare,
  1755. { 0,
  1756. 0,
  1757. 0,
  1758. 0,
  1759. VT_EMPTY_EQ,
  1760. VT_EMPTY_NE,
  1761. 0,
  1762. 0,
  1763. 0 },
  1764. { 0,
  1765. 0,
  1766. 0,
  1767. 0,
  1768. VTP_EMPTY_EQ,
  1769. VTP_EMPTY_NE,
  1770. 0,
  1771. 0,
  1772. 0 },
  1773. },
  1774. // VT_NULL
  1775. { VT_NULL_Compare, VTP_NULL_Compare,
  1776. { 0,
  1777. 0,
  1778. 0,
  1779. 0,
  1780. VT_NULL_EQ,
  1781. VT_NULL_NE,
  1782. 0,
  1783. 0,
  1784. 0 },
  1785. { 0,
  1786. 0,
  1787. 0,
  1788. 0,
  1789. VTP_NULL_EQ,
  1790. VTP_NULL_NE,
  1791. 0,
  1792. 0,
  1793. 0 },
  1794. },
  1795. // VT_I2
  1796. { VT_I2_Compare, VTP_I2_Compare,
  1797. { VT_I2_LT,
  1798. VT_I2_LE,
  1799. VT_I2_GT,
  1800. VT_I2_GE,
  1801. VT_I2_EQ,
  1802. VT_I2_NE,
  1803. 0,
  1804. VT_I2_AllBits,
  1805. VT_I2_SomeBits
  1806. },
  1807. { VTP_I2_LT,
  1808. VTP_I2_LE,
  1809. VTP_I2_GT,
  1810. VTP_I2_GE,
  1811. VTP_I2_EQ,
  1812. VTP_I2_NE,
  1813. 0,
  1814. VTP_I2_AllBits,
  1815. VTP_I2_SomeBits
  1816. },
  1817. },
  1818. // VT_I4
  1819. { VT_I4_Compare, VTP_I4_Compare,
  1820. { VT_I4_LT,
  1821. VT_I4_LE,
  1822. VT_I4_GT,
  1823. VT_I4_GE,
  1824. VT_I4_EQ,
  1825. VT_I4_NE,
  1826. 0,
  1827. VT_I4_AllBits,
  1828. VT_I4_SomeBits
  1829. },
  1830. { VTP_I4_LT,
  1831. VTP_I4_LE,
  1832. VTP_I4_GT,
  1833. VTP_I4_GE,
  1834. VTP_I4_EQ,
  1835. VTP_I4_NE,
  1836. 0,
  1837. VTP_I4_AllBits,
  1838. VTP_I4_SomeBits
  1839. },
  1840. },
  1841. // VT_R4
  1842. { VT_R4_Compare, VTP_R4_Compare,
  1843. { VT_R4_LT,
  1844. VT_R4_LE,
  1845. VT_R4_GT,
  1846. VT_R4_GE,
  1847. VT_R4_EQ,
  1848. VT_R4_NE,
  1849. 0,
  1850. 0,
  1851. 0,
  1852. },
  1853. { VTP_R4_LT,
  1854. VTP_R4_LE,
  1855. VTP_R4_GT,
  1856. VTP_R4_GE,
  1857. VTP_R4_EQ,
  1858. VTP_R4_NE,
  1859. 0,
  1860. 0,
  1861. 0,
  1862. },
  1863. },
  1864. // VT_R8
  1865. { VT_R8_Compare, VTP_R8_Compare,
  1866. { VT_R8_LT,
  1867. VT_R8_LE,
  1868. VT_R8_GT,
  1869. VT_R8_GE,
  1870. VT_R8_EQ,
  1871. VT_R8_NE,
  1872. 0,
  1873. 0,
  1874. 0,
  1875. },
  1876. { VTP_R8_LT,
  1877. VTP_R8_LE,
  1878. VTP_R8_GT,
  1879. VTP_R8_GE,
  1880. VTP_R8_EQ,
  1881. VTP_R8_NE,
  1882. 0,
  1883. 0,
  1884. 0,
  1885. },
  1886. },
  1887. // VT_CY
  1888. { VT_I8_Compare, VTP_I8_Compare,
  1889. { VT_I8_LT,
  1890. VT_I8_LE,
  1891. VT_I8_GT,
  1892. VT_I8_GE,
  1893. VT_I8_EQ,
  1894. VT_I8_NE,
  1895. 0,
  1896. 0,
  1897. 0
  1898. },
  1899. { VTP_I8_LT,
  1900. VTP_I8_LE,
  1901. VTP_I8_GT,
  1902. VTP_I8_GE,
  1903. VTP_I8_EQ,
  1904. VTP_I8_NE,
  1905. 0,
  1906. 0,
  1907. 0
  1908. },
  1909. },
  1910. // VT_DATE
  1911. { VT_R8_Compare, VTP_R8_Compare,
  1912. { VT_R8_LT,
  1913. VT_R8_LE,
  1914. VT_R8_GT,
  1915. VT_R8_GE,
  1916. VT_R8_EQ,
  1917. VT_R8_NE,
  1918. 0,
  1919. 0,
  1920. 0,
  1921. },
  1922. { VTP_R8_LT,
  1923. VTP_R8_LE,
  1924. VTP_R8_GT,
  1925. VTP_R8_GE,
  1926. VTP_R8_EQ,
  1927. VTP_R8_NE,
  1928. 0,
  1929. 0,
  1930. 0,
  1931. },
  1932. },
  1933. // VT_BSTR
  1934. { VT_BSTR_Compare, VTP_BSTR_Compare,
  1935. { VT_BSTR_LT,
  1936. VT_BSTR_LE,
  1937. VT_BSTR_GT,
  1938. VT_BSTR_GE,
  1939. VT_BSTR_EQ,
  1940. VT_BSTR_NE,
  1941. 0,
  1942. 0,
  1943. 0
  1944. },
  1945. { VTP_BSTR_LT,
  1946. VTP_BSTR_LE,
  1947. VTP_BSTR_GT,
  1948. VTP_BSTR_GE,
  1949. VTP_BSTR_EQ,
  1950. VTP_BSTR_NE,
  1951. 0,
  1952. 0,
  1953. 0
  1954. },
  1955. },
  1956. // VT_DISPATCH
  1957. { 0, 0,
  1958. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  1959. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  1960. },
  1961. // VT_ERROR
  1962. { VT_I4_Compare, VTP_I4_Compare,
  1963. { VT_I4_LT,
  1964. VT_I4_LE,
  1965. VT_I4_GT,
  1966. VT_I4_GE,
  1967. VT_I4_EQ,
  1968. VT_I4_NE,
  1969. 0,
  1970. VT_I4_AllBits,
  1971. VT_I4_SomeBits
  1972. },
  1973. { VTP_I4_LT,
  1974. VTP_I4_LE,
  1975. VTP_I4_GT,
  1976. VTP_I4_GE,
  1977. VTP_I4_EQ,
  1978. VTP_I4_NE,
  1979. 0,
  1980. VTP_I4_AllBits,
  1981. VTP_I4_SomeBits
  1982. },
  1983. },
  1984. // VT_BOOL
  1985. { VT_BOOL_Compare, VTP_BOOL_Compare,
  1986. { 0,
  1987. 0,
  1988. 0,
  1989. 0,
  1990. VT_BOOL_EQ,
  1991. VT_BOOL_NE,
  1992. 0,
  1993. 0,
  1994. 0
  1995. },
  1996. { 0,
  1997. 0,
  1998. 0,
  1999. 0,
  2000. VTP_BOOL_EQ,
  2001. VTP_BOOL_NE,
  2002. 0,
  2003. 0,
  2004. 0
  2005. },
  2006. },
  2007. // VT_VARIANT
  2008. { VT_VARIANT_Compare, VTP_VARIANT_Compare,
  2009. { VT_VARIANT_LT,
  2010. VT_VARIANT_LE,
  2011. VT_VARIANT_GT,
  2012. VT_VARIANT_GE,
  2013. VT_VARIANT_EQ,
  2014. VT_VARIANT_NE,
  2015. 0,
  2016. 0,
  2017. 0,
  2018. },
  2019. { VTP_VARIANT_LT,
  2020. VTP_VARIANT_LE,
  2021. VTP_VARIANT_GT,
  2022. VTP_VARIANT_GE,
  2023. VTP_VARIANT_EQ,
  2024. VTP_VARIANT_NE,
  2025. 0,
  2026. 0,
  2027. 0,
  2028. },
  2029. },
  2030. // VT_UNKNOWN
  2031. { 0, 0,
  2032. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2033. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2034. },
  2035. // VT_DECIMAL
  2036. { VT_DEC_Compare, VTP_DEC_Compare,
  2037. { VT_DEC_LT,
  2038. VT_DEC_LE,
  2039. VT_DEC_GT,
  2040. VT_DEC_GE,
  2041. VT_DEC_EQ,
  2042. VT_DEC_NE,
  2043. 0,
  2044. 0,
  2045. 0
  2046. },
  2047. { VTP_DEC_LT,
  2048. VTP_DEC_LE,
  2049. VTP_DEC_GT,
  2050. VTP_DEC_GE,
  2051. VTP_DEC_EQ,
  2052. VTP_DEC_NE,
  2053. 0,
  2054. 0,
  2055. 0
  2056. },
  2057. },
  2058. // VARENUM value 15 unused
  2059. { 0, 0,
  2060. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2061. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2062. },
  2063. // VT_I1
  2064. { VT_I1_Compare, VTP_I1_Compare,
  2065. { VT_I1_LT,
  2066. VT_I1_LE,
  2067. VT_I1_GT,
  2068. VT_I1_GE,
  2069. VT_I1_EQ,
  2070. VT_I1_NE,
  2071. 0,
  2072. VT_I1_AllBits,
  2073. VT_I1_SomeBits
  2074. },
  2075. { VTP_I1_LT,
  2076. VTP_I1_LE,
  2077. VTP_I1_GT,
  2078. VTP_I1_GE,
  2079. VTP_I1_EQ,
  2080. VTP_I1_NE,
  2081. 0,
  2082. VTP_I1_AllBits,
  2083. VTP_I1_SomeBits
  2084. },
  2085. },
  2086. // VT_UI1
  2087. { VT_UI1_Compare, VTP_UI1_Compare,
  2088. { VT_UI1_LT,
  2089. VT_UI1_LE,
  2090. VT_UI1_GT,
  2091. VT_UI1_GE,
  2092. VT_UI1_EQ,
  2093. VT_UI1_NE,
  2094. 0,
  2095. VT_UI1_AllBits,
  2096. VT_UI1_SomeBits
  2097. },
  2098. { VTP_UI1_LT,
  2099. VTP_UI1_LE,
  2100. VTP_UI1_GT,
  2101. VTP_UI1_GE,
  2102. VTP_UI1_EQ,
  2103. VTP_UI1_NE,
  2104. 0,
  2105. VTP_UI1_AllBits,
  2106. VTP_UI1_SomeBits
  2107. },
  2108. },
  2109. // VT_UI2
  2110. { VT_UI2_Compare, VTP_UI2_Compare,
  2111. { VT_UI2_LT,
  2112. VT_UI2_LE,
  2113. VT_UI2_GT,
  2114. VT_UI2_GE,
  2115. VT_UI2_EQ,
  2116. VT_UI2_NE,
  2117. 0,
  2118. VT_UI2_AllBits,
  2119. VT_UI2_SomeBits
  2120. },
  2121. { VTP_UI2_LT,
  2122. VTP_UI2_LE,
  2123. VTP_UI2_GT,
  2124. VTP_UI2_GE,
  2125. VTP_UI2_EQ,
  2126. VTP_UI2_NE,
  2127. 0,
  2128. VTP_UI2_AllBits,
  2129. VTP_UI2_SomeBits
  2130. },
  2131. },
  2132. // VT_UI4
  2133. { VT_UI4_Compare, VTP_UI4_Compare,
  2134. { VT_UI4_LT,
  2135. VT_UI4_LE,
  2136. VT_UI4_GT,
  2137. VT_UI4_GE,
  2138. VT_UI4_EQ,
  2139. VT_UI4_NE,
  2140. 0,
  2141. VT_UI4_AllBits,
  2142. VT_UI4_SomeBits
  2143. },
  2144. { VTP_UI4_LT,
  2145. VTP_UI4_LE,
  2146. VTP_UI4_GT,
  2147. VTP_UI4_GE,
  2148. VTP_UI4_EQ,
  2149. VTP_UI4_NE,
  2150. 0,
  2151. VTP_UI4_AllBits,
  2152. VTP_UI4_SomeBits
  2153. },
  2154. },
  2155. // VT_I8
  2156. { VT_I8_Compare, VTP_I8_Compare,
  2157. { VT_I8_LT,
  2158. VT_I8_LE,
  2159. VT_I8_GT,
  2160. VT_I8_GE,
  2161. VT_I8_EQ,
  2162. VT_I8_NE,
  2163. 0,
  2164. VT_I8_AllBits,
  2165. VT_I8_SomeBits
  2166. },
  2167. { VTP_I8_LT,
  2168. VTP_I8_LE,
  2169. VTP_I8_GT,
  2170. VTP_I8_GE,
  2171. VTP_I8_EQ,
  2172. VTP_I8_NE,
  2173. 0,
  2174. VTP_I8_AllBits,
  2175. VTP_I8_SomeBits
  2176. },
  2177. },
  2178. // VT_UI8
  2179. { VT_UI8_Compare, VTP_UI8_Compare,
  2180. { VT_UI8_LT,
  2181. VT_UI8_LE,
  2182. VT_UI8_GT,
  2183. VT_UI8_GE,
  2184. VT_UI8_EQ,
  2185. VT_UI8_NE,
  2186. 0,
  2187. VT_UI8_AllBits,
  2188. VT_UI8_SomeBits
  2189. },
  2190. { VTP_UI8_LT,
  2191. VTP_UI8_LE,
  2192. VTP_UI8_GT,
  2193. VTP_UI8_GE,
  2194. VTP_UI8_EQ,
  2195. VTP_UI8_NE,
  2196. 0,
  2197. VTP_UI8_AllBits,
  2198. VTP_UI8_SomeBits
  2199. },
  2200. },
  2201. // VT_INT
  2202. { VT_I4_Compare, VTP_I4_Compare,
  2203. { VT_I4_LT,
  2204. VT_I4_LE,
  2205. VT_I4_GT,
  2206. VT_I4_GE,
  2207. VT_I4_EQ,
  2208. VT_I4_NE,
  2209. 0,
  2210. VT_I4_AllBits,
  2211. VT_I4_SomeBits
  2212. },
  2213. { VTP_I4_LT,
  2214. VTP_I4_LE,
  2215. VTP_I4_GT,
  2216. VTP_I4_GE,
  2217. VTP_I4_EQ,
  2218. VTP_I4_NE,
  2219. 0,
  2220. VTP_I4_AllBits,
  2221. VTP_I4_SomeBits
  2222. },
  2223. },
  2224. // VT_UINT
  2225. { VT_UI4_Compare, VTP_UI4_Compare,
  2226. { VT_UI4_LT,
  2227. VT_UI4_LE,
  2228. VT_UI4_GT,
  2229. VT_UI4_GE,
  2230. VT_UI4_EQ,
  2231. VT_UI4_NE,
  2232. 0,
  2233. VT_UI4_AllBits,
  2234. VT_UI4_SomeBits
  2235. },
  2236. { VTP_UI4_LT,
  2237. VTP_UI4_LE,
  2238. VTP_UI4_GT,
  2239. VTP_UI4_GE,
  2240. VTP_UI4_EQ,
  2241. VTP_UI4_NE,
  2242. 0,
  2243. VTP_UI4_AllBits,
  2244. VTP_UI4_SomeBits
  2245. },
  2246. },
  2247. // VT_VOID
  2248. { 0, 0,
  2249. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2250. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2251. },
  2252. // VT_HRESULT
  2253. { VT_I4_Compare, VTP_I4_Compare,
  2254. { VT_I4_LT,
  2255. VT_I4_LE,
  2256. VT_I4_GT,
  2257. VT_I4_GE,
  2258. VT_I4_EQ,
  2259. VT_I4_NE,
  2260. 0,
  2261. VT_I4_AllBits,
  2262. VT_I4_SomeBits
  2263. },
  2264. { VTP_I4_LT,
  2265. VTP_I4_LE,
  2266. VTP_I4_GT,
  2267. VTP_I4_GE,
  2268. VTP_I4_EQ,
  2269. VTP_I4_NE,
  2270. 0,
  2271. VTP_I4_AllBits,
  2272. VTP_I4_SomeBits
  2273. },
  2274. },
  2275. // VT_PTR
  2276. { 0, 0,
  2277. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2278. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2279. },
  2280. // VT_SAFEARRAY
  2281. { 0, 0,
  2282. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2283. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2284. },
  2285. // VT_CARRAY
  2286. { 0, 0,
  2287. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2288. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2289. },
  2290. // VT_USERDEFINED
  2291. { 0, 0,
  2292. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2293. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2294. },
  2295. // VT_LPSTR
  2296. { VT_LPSTR_Compare, VTP_LPSTR_Compare,
  2297. { VT_LPSTR_LT,
  2298. VT_LPSTR_LE,
  2299. VT_LPSTR_GT,
  2300. VT_LPSTR_GE,
  2301. VT_LPSTR_EQ,
  2302. VT_LPSTR_NE,
  2303. 0,
  2304. 0,
  2305. 0
  2306. },
  2307. { VTP_LPSTR_LT,
  2308. VTP_LPSTR_LE,
  2309. VTP_LPSTR_GT,
  2310. VTP_LPSTR_GE,
  2311. VTP_LPSTR_EQ,
  2312. VTP_LPSTR_NE,
  2313. 0,
  2314. 0,
  2315. 0
  2316. },
  2317. },
  2318. // VT_LPWSTR
  2319. { VT_LPWSTR_Compare, VTP_LPWSTR_Compare,
  2320. { VT_LPWSTR_LT,
  2321. VT_LPWSTR_LE,
  2322. VT_LPWSTR_GT,
  2323. VT_LPWSTR_GE,
  2324. VT_LPWSTR_EQ,
  2325. VT_LPWSTR_NE,
  2326. 0,
  2327. 0,
  2328. 0
  2329. },
  2330. { VTP_LPWSTR_LT,
  2331. VTP_LPWSTR_LE,
  2332. VTP_LPWSTR_GT,
  2333. VTP_LPWSTR_GE,
  2334. VTP_LPWSTR_EQ,
  2335. VTP_LPWSTR_NE,
  2336. 0,
  2337. 0,
  2338. 0
  2339. },
  2340. }
  2341. };
  2342. ULONG const CComparators::_cVariantComparators =
  2343. sizeof(CComparators::_aVariantComparators) /
  2344. sizeof(CComparators::_aVariantComparators[0]);
  2345. ULONG const CComparators::_iStart2 = VT_FILETIME;
  2346. CComparators::SComparators const CComparators::_aVariantComparators2[] = {
  2347. // VT_FILETIME
  2348. { VT_UI8_Compare, VTP_UI8_Compare,
  2349. { VT_UI8_LT,
  2350. VT_UI8_LE,
  2351. VT_UI8_GT,
  2352. VT_UI8_GE,
  2353. VT_UI8_EQ,
  2354. VT_UI8_NE,
  2355. 0,
  2356. 0,
  2357. 0
  2358. },
  2359. { VTP_UI8_LT,
  2360. VTP_UI8_LE,
  2361. VTP_UI8_GT,
  2362. VTP_UI8_GE,
  2363. VTP_UI8_EQ,
  2364. VTP_UI8_NE,
  2365. 0,
  2366. 0,
  2367. 0
  2368. },
  2369. },
  2370. // VT_BLOB
  2371. { VT_BLOB_Compare, VTP_BLOB_Compare,
  2372. { VT_BLOB_LT,
  2373. VT_BLOB_LE,
  2374. VT_BLOB_GT,
  2375. VT_BLOB_GE,
  2376. VT_BLOB_EQ,
  2377. VT_BLOB_NE,
  2378. 0,
  2379. 0,
  2380. 0
  2381. },
  2382. { VTP_BLOB_LT,
  2383. VTP_BLOB_LE,
  2384. VTP_BLOB_GT,
  2385. VTP_BLOB_GE,
  2386. VTP_BLOB_EQ,
  2387. VTP_BLOB_NE,
  2388. 0,
  2389. 0,
  2390. 0
  2391. },
  2392. },
  2393. // VT_STREAM
  2394. { 0, 0,
  2395. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2396. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2397. },
  2398. // VT_STORAGE
  2399. { 0, 0,
  2400. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2401. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2402. },
  2403. // VT_STREAMED_OBJECT
  2404. { 0, 0,
  2405. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2406. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2407. },
  2408. // VT_STORED_OBJECT
  2409. { 0, 0,
  2410. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2411. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2412. },
  2413. // VT_BLOB_OBJECT
  2414. { VT_BLOB_Compare, VTP_BLOB_Compare,
  2415. { VT_BLOB_LT,
  2416. VT_BLOB_LE,
  2417. VT_BLOB_GT,
  2418. VT_BLOB_GE,
  2419. VT_BLOB_EQ,
  2420. VT_BLOB_NE,
  2421. 0,
  2422. 0,
  2423. 0
  2424. },
  2425. { VTP_BLOB_LT,
  2426. VTP_BLOB_LE,
  2427. VTP_BLOB_GT,
  2428. VTP_BLOB_GE,
  2429. VTP_BLOB_EQ,
  2430. VTP_BLOB_NE,
  2431. 0,
  2432. 0,
  2433. 0
  2434. },
  2435. },
  2436. // VT_CF
  2437. { VT_CF_Compare, VTP_CF_Compare,
  2438. { VT_CF_LT,
  2439. VT_CF_LE,
  2440. VT_CF_GT,
  2441. VT_CF_GE,
  2442. VT_CF_EQ,
  2443. VT_CF_NE,
  2444. 0,
  2445. 0,
  2446. 0
  2447. },
  2448. { VTP_CF_LT,
  2449. VTP_CF_LE,
  2450. VTP_CF_GT,
  2451. VTP_CF_GE,
  2452. VTP_CF_EQ,
  2453. VTP_CF_NE,
  2454. 0,
  2455. 0,
  2456. 0
  2457. },
  2458. },
  2459. // VT_CLSID
  2460. { VT_CLSID_Compare, 0, // Vector special-cased in GetPointerComparator
  2461. { 0,
  2462. 0,
  2463. 0,
  2464. 0,
  2465. VT_CLSID_EQ,
  2466. VT_CLSID_NE,
  2467. 0,
  2468. 0,
  2469. 0
  2470. },
  2471. { 0,
  2472. 0,
  2473. 0,
  2474. 0,
  2475. 0, // Special-cased in GetPointerRelop
  2476. 0, // Special-cased in GetPointerRelop
  2477. 0,
  2478. 0,
  2479. 0
  2480. },
  2481. }
  2482. };
  2483. ULONG const CComparators::_cVariantComparators2 =
  2484. sizeof(CComparators::_aVariantComparators2) /
  2485. sizeof(CComparators::_aVariantComparators2[0]);
  2486. ULONG const CComparators::_iStart3 = DBTYPE_BYTES;
  2487. CComparators::SComparators const CComparators::_aVariantComparators3[] = {
  2488. // DBTYPE_BYTES
  2489. { 0, 0,
  2490. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2491. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2492. },
  2493. // DBTYPE_STR
  2494. { 0, 0,
  2495. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2496. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2497. },
  2498. // DBTYPE_WSTR
  2499. { 0, 0,
  2500. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2501. { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  2502. }
  2503. };
  2504. ULONG const CComparators::_cVariantComparators3 =
  2505. sizeof(CComparators::_aVariantComparators3) /
  2506. sizeof(CComparators::_aVariantComparators3[0]);
  2507. ULONG const SortDescend = 1;
  2508. ULONG const SortNullFirst = 2;
  2509. //+-------------------------------------------------------------------------
  2510. //
  2511. // Member: CComparePropSets::Init, public
  2512. //
  2513. // Synopsis: [Re] Initializes property comparator to use a different
  2514. // sort order.
  2515. //
  2516. // Arguments: [cCols] -- Count of columns
  2517. // [aKey] -- Sort keys
  2518. // [aColIndex] -- Index of column in sort key
  2519. //
  2520. // History: 16-Jun-92 KyleP Created
  2521. //
  2522. //--------------------------------------------------------------------------
  2523. void CComparePropSets::Init( int cCols,
  2524. CSortSet const * pSort,
  2525. int aColIndex[] )
  2526. {
  2527. Win4Assert( QUERY_SORTASCEND == 0 );
  2528. Win4Assert( QUERY_SORTDESCEND == SortDescend );
  2529. Win4Assert( (QUERY_SORTXASCEND & SortNullFirst) == SortNullFirst );
  2530. Win4Assert( (QUERY_SORTXDESCEND & SortNullFirst) == SortNullFirst );
  2531. delete _aColComp;
  2532. _aColComp = 0;
  2533. if ( cCols > 0 )
  2534. {
  2535. _cColComp = cCols;
  2536. _aColComp = new SColCompare[ _cColComp ];
  2537. for ( UINT i = 0; i < _cColComp; i++ )
  2538. {
  2539. if (0 == aColIndex)
  2540. _aColComp[i]._iCol = i;
  2541. else
  2542. _aColComp[i]._iCol = aColIndex[i];
  2543. _aColComp[i]._dir = pSort->Get(i).dwOrder;
  2544. _aColComp[i]._DirMult =
  2545. ( ( _aColComp[i]._dir & SortDescend ) != 0 ) ? -1 : 1;
  2546. _aColComp[i]._pt = VT_EMPTY;
  2547. _aColComp[i]._comp = VT_EMPTY_Compare;
  2548. }
  2549. }
  2550. }
  2551. //+-------------------------------------------------------------------------
  2552. //
  2553. // Member: CComparePropSets::Init, public
  2554. //
  2555. // Synopsis: [Re] Initializes property comparator to use a different
  2556. // sort order. Assumes ascending order. Mostly useful for
  2557. // equality testing.
  2558. //
  2559. // Arguments: [pCols] -- Columns
  2560. // [aColIndex] -- Index of column in sort key
  2561. //
  2562. // History: 02-Nov-93 KyleP Created
  2563. //
  2564. //--------------------------------------------------------------------------
  2565. void CComparePropSets::Init( CColumnSet const & cols )
  2566. {
  2567. Win4Assert( cols.Size() > 0 );
  2568. delete _aColComp;
  2569. _aColComp = 0;
  2570. _cColComp = cols.Size();
  2571. _aColComp = new SColCompare[ _cColComp ];
  2572. for ( UINT i = 0; i < _cColComp; i++ )
  2573. {
  2574. _aColComp[i]._iCol = i;
  2575. _aColComp[i]._dir = 0;
  2576. _aColComp[i]._DirMult = 1;
  2577. _aColComp[i]._pt = VT_EMPTY;
  2578. _aColComp[i]._comp = VT_EMPTY_Compare;
  2579. }
  2580. }
  2581. //+-------------------------------------------------------------------------
  2582. //
  2583. // Member: CComparePropSets::Compare, public
  2584. //
  2585. // Synopsis: Compares two rows (property sets).
  2586. //
  2587. // Arguments: [row1] -- First row.
  2588. // [row2] -- Second row.
  2589. //
  2590. // Returns: Column # where row1 > row2 or negative column # where row1
  2591. // < row2 or 0 if row1 = row2.
  2592. // This odd return code is useful for categorization, so it
  2593. // knows the column at which the rows differ.
  2594. //
  2595. // History: 27-Jun-96 dlee Created
  2596. //
  2597. //--------------------------------------------------------------------------
  2598. int CComparePropSets::Compare( PROPVARIANT ** row1, PROPVARIANT ** row2 )
  2599. {
  2600. Win4Assert( !IsEmpty() );
  2601. Win4Assert( VT_EMPTY == 0 );
  2602. Win4Assert( VT_NULL == 1 );
  2603. int idiff = 0;
  2604. for ( UINT i = 0; i < _cColComp; i++ )
  2605. {
  2606. ULONG ptRow1 = row1[_aColComp[i]._iCol]->vt;
  2607. ULONG ptRow2 = row2[_aColComp[i]._iCol]->vt;
  2608. //
  2609. // If the property types are incompatible, then 'sort' according
  2610. // to type. VT_EMPTY and VT_NULL will sort to beginning.
  2611. //
  2612. if ( ptRow1 != ptRow2 )
  2613. {
  2614. idiff = ptRow2 - ptRow1;
  2615. break;
  2616. }
  2617. if ( ptRow1 != _aColComp[i]._pt )
  2618. _UpdateCompare( i, (VARENUM) ptRow1 );
  2619. Win4Assert( _aColComp[i]._comp != 0 );
  2620. idiff = _aColComp[i]._comp( *row1[_aColComp[i]._iCol],
  2621. *row2[_aColComp[i]._iCol] ) *
  2622. _aColComp[i]._DirMult;
  2623. if ( 0 != idiff )
  2624. break;
  2625. }
  2626. if ( idiff < 0 )
  2627. return - (int) ( i + 1 );
  2628. if ( idiff > 0 )
  2629. return i + 1;
  2630. return 0;
  2631. }
  2632. //+-------------------------------------------------------------------------
  2633. //
  2634. // Member: CComparePropSets::IsLT, public
  2635. //
  2636. // Synopsis: Compares two rows (property sets).
  2637. //
  2638. // Arguments: [row1] -- First row.
  2639. // [row2] -- Second row.
  2640. //
  2641. // Returns: TRUE if row1 < row2, FALSE otherwise
  2642. //
  2643. // History: 16-Jun-92 KyleP Created
  2644. //
  2645. //--------------------------------------------------------------------------
  2646. BOOL CComparePropSets::IsLT( PROPVARIANT ** row1, PROPVARIANT ** row2 )
  2647. {
  2648. int idiff = Compare( row1, row2 );
  2649. return ( idiff < 0 );
  2650. }
  2651. //+-------------------------------------------------------------------------
  2652. //
  2653. // Member: CComparePropSets::IsGT, public
  2654. //
  2655. // Synopsis: Compares two rows (property sets).
  2656. //
  2657. // Arguments: [row1] -- First row.
  2658. // [row2] -- Second row.
  2659. //
  2660. // Returns: TRUE if row1 > row2, FALSE otherwise
  2661. //
  2662. // History: 16-Jun-92 KyleP Created
  2663. //
  2664. //--------------------------------------------------------------------------
  2665. BOOL CComparePropSets::IsGT( PROPVARIANT ** row1, PROPVARIANT ** row2 )
  2666. {
  2667. int idiff = Compare( row1, row2 );
  2668. return ( idiff > 0 );
  2669. }
  2670. //+-------------------------------------------------------------------------
  2671. //
  2672. // Member: CComparePropSets::IsEQ, public
  2673. //
  2674. // Synopsis: Compares two rows (property sets).
  2675. //
  2676. // Arguments: [row1] -- First row.
  2677. // [row2] -- Second row.
  2678. //
  2679. // Returns: TRUE if [row1] == [row2].
  2680. //
  2681. // History: 02-Nov-93 KyleP Created
  2682. //
  2683. //--------------------------------------------------------------------------
  2684. BOOL CComparePropSets::IsEQ( PROPVARIANT ** row1, PROPVARIANT ** row2 )
  2685. {
  2686. int idiff = Compare( row1, row2 );
  2687. return ( 0 == idiff );
  2688. }
  2689. //+-------------------------------------------------------------------------
  2690. //
  2691. // Member: CComparePropSets::_UpdateCompare, private
  2692. //
  2693. // Effects: Adds the appropriate comparator for column [iCol].
  2694. //
  2695. // Arguments: [iCol] -- Column to modify.
  2696. // [pt] -- New property type.
  2697. //
  2698. // History: 16-Jun-92 KyleP Created
  2699. //
  2700. //--------------------------------------------------------------------------
  2701. void CComparePropSets::_UpdateCompare( UINT iCol, VARENUM vt )
  2702. {
  2703. _aColComp[iCol]._pt = vt;
  2704. _aColComp[iCol]._comp = VariantCompare.GetComparator( vt );
  2705. if ( 0 == _aColComp[iCol]._comp )
  2706. _aColComp[iCol]._comp = VT_DEFAULT_Compare;
  2707. }
  2708. inline void ConvertArrayToVector ( PROPVARIANT const & vIn, PROPVARIANT & vOut )
  2709. {
  2710. Win4Assert( vIn.vt & VT_ARRAY );
  2711. SAFEARRAY * pSa = vIn.parray;
  2712. ULONG cDataElements = 1;
  2713. for ( unsigned i = 0; i < pSa->cDims; i++ )
  2714. {
  2715. cDataElements *= pSa->rgsabound[i].cElements;
  2716. }
  2717. vOut.vt = (vIn.vt & VT_TYPEMASK) | VT_VECTOR;
  2718. vOut.caub.cElems = cDataElements;
  2719. vOut.caub.pElems = (BYTE *)pSa->pvData;
  2720. }
  2721. BYTE * _GetNth( PROPVARIANT const & v, unsigned i )
  2722. {
  2723. Win4Assert( isVector(v) );
  2724. switch ( getBaseType( v ) )
  2725. {
  2726. case VT_I1 :
  2727. return (BYTE *) & (v.caub.pElems[i]);
  2728. case VT_UI1 :
  2729. return (BYTE *) & (v.caub.pElems[i]);
  2730. case VT_I2 :
  2731. return (BYTE *) & (v.cai.pElems[i]);
  2732. case VT_UI2 :
  2733. return (BYTE *) & (v.caui.pElems[i]);
  2734. case VT_BOOL :
  2735. return (BYTE *) & (v.cabool.pElems[i]);
  2736. case VT_I4 :
  2737. case VT_INT :
  2738. return (BYTE *) & (v.cal.pElems[i]);
  2739. case VT_UI4 :
  2740. case VT_UINT :
  2741. return (BYTE *) & (v.caul.pElems[i]);
  2742. case VT_R4 :
  2743. return (BYTE *) & (v.caflt.pElems[i]);
  2744. case VT_ERROR :
  2745. return (BYTE *) & (v.cascode.pElems[i]);
  2746. case VT_I8 :
  2747. return (BYTE *) & (v.cah.pElems[i]);
  2748. case VT_UI8 :
  2749. return (BYTE *) & (v.cauh.pElems[i]);
  2750. case VT_R8 :
  2751. return (BYTE *) & (v.cadbl.pElems[i]);
  2752. case VT_CY :
  2753. return (BYTE *) & (v.cacy.pElems[i]);
  2754. case VT_DATE :
  2755. return (BYTE *) & (v.cadate.pElems[i]);
  2756. case VT_FILETIME :
  2757. return (BYTE *) & (v.cafiletime.pElems[i]);
  2758. case VT_CLSID :
  2759. return (BYTE *) & (v.cauuid.pElems[i]);
  2760. case VT_CF :
  2761. return (BYTE *) & (v.caclipdata.pElems[i]);
  2762. case VT_BSTR :
  2763. return (BYTE *) & (v.cabstr.pElems[i]);
  2764. case VT_LPSTR :
  2765. return (BYTE *) & (v.calpstr.pElems[i]);
  2766. case VT_LPWSTR :
  2767. return (BYTE *) & (v.calpwstr.pElems[i]);
  2768. case VT_VARIANT :
  2769. return (BYTE *) & (v.capropvar.pElems[i]);
  2770. case VT_DECIMAL :
  2771. // NOTE: not valid in a vector, but it could occur due to the
  2772. // simplistic conversion of arrays to vectors.
  2773. DECIMAL * paDec = (DECIMAL *) v.caub.pElems;
  2774. return (BYTE *) (paDec + i);
  2775. }
  2776. Win4Assert(!"illegal base variant type in vector compare");
  2777. return 0;
  2778. } //_GetNth
  2779. //+-------------------------------------------------------------------------
  2780. //
  2781. // Member: VT_VECTOR_Compare, public
  2782. //
  2783. // Effects: Compares two property values, intended to be called when
  2784. // at least one of the arguments is a vector
  2785. //
  2786. // Arguments: [v1] -- 1st variant to compare
  2787. // [v2] -- 2nd variant to compare
  2788. //
  2789. // History: 1-May-95 dlee Created
  2790. //
  2791. //--------------------------------------------------------------------------
  2792. int VT_VECTOR_Compare( PROPVARIANT const & v1In, PROPVARIANT const & v2In )
  2793. {
  2794. // must be the same datatype, or just sort on type
  2795. if ( ( v1In.vt != v2In.vt ) )
  2796. return v1In.vt - v2In.vt;
  2797. PROPVARIANT v1 = v1In;
  2798. PROPVARIANT v2 = v2In;
  2799. if ( isArray(v1In) )
  2800. {
  2801. Win4Assert( isArray(v2In) );
  2802. SAFEARRAY * pSa1 = v1In.parray;
  2803. SAFEARRAY * pSa2 = v2In.parray;
  2804. if (pSa1->cDims != pSa2->cDims)
  2805. return pSa1->cDims - pSa2->cDims;
  2806. ULONG cDataElements = 1;
  2807. for ( unsigned i = 0; i < pSa1->cDims; i++ )
  2808. {
  2809. if ( pSa1->rgsabound[i].lLbound != pSa2->rgsabound[i].lLbound )
  2810. return pSa1->rgsabound[i].lLbound - pSa2->rgsabound[i].lLbound;
  2811. if ( pSa1->rgsabound[i].cElements != pSa2->rgsabound[i].cElements )
  2812. return pSa1->rgsabound[i].cElements - pSa2->rgsabound[i].cElements;
  2813. cDataElements *= pSa1->rgsabound[i].cElements;
  2814. }
  2815. //
  2816. // arrays match in type, total size and dimensions. Compare as vectors.
  2817. //
  2818. v1.vt = v2.vt = (v1In.vt & VT_TYPEMASK) | VT_VECTOR;
  2819. v1.caub.cElems = v2.caub.cElems = cDataElements;
  2820. v1.caub.pElems = (BYTE *)pSa1->pvData;
  2821. v2.caub.pElems = (BYTE *)pSa2->pvData;
  2822. }
  2823. Win4Assert( isVector(v1) );
  2824. FPCmp cmp = VariantCompare.GetPointerComparator( v1, v2 );
  2825. if (0 == cmp)
  2826. {
  2827. // vector of an unhandled type
  2828. ciDebugOut(( DEB_ERROR,
  2829. "Unknown property type %d (%x) used in comparison.\n",
  2830. v1.vt, v1.vt ));
  2831. Win4Assert(! "VT_VECTOR_Compare: vector compare of unhandled type" );
  2832. return 0;
  2833. }
  2834. unsigned cMin = __min( v1.cal.cElems, v2.cal.cElems );
  2835. for ( unsigned x = 0; x < cMin; x++ )
  2836. {
  2837. int r = cmp( _GetNth( v1, x), _GetNth( v2, x ) );
  2838. if (0 != r)
  2839. return r;
  2840. }
  2841. // All equal so far up to the minimum cardinality of the vectors.
  2842. // Any difference now would be due to the cardinality.
  2843. return v1.cal.cElems - v2.cal.cElems;
  2844. } //VT_VECTOR_Compare
  2845. int VTP_VECTOR_Compare( BYTE const *pv1, BYTE const *pv2 )
  2846. {
  2847. return VT_VECTOR_Compare( ** (PROPVARIANT **) pv1,
  2848. ** (PROPVARIANT **) pv2 );
  2849. } //VTP_VECTOR_Compare
  2850. BOOL VT_VECTOR_LT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2851. {
  2852. return VT_VECTOR_Compare( v1, v2 ) < 0;
  2853. } //VT_VECTOR_LT
  2854. BOOL VT_VECTOR_LE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2855. {
  2856. return VT_VECTOR_Compare( v1, v2 ) <= 0;
  2857. } //VT_VECTOR_LE
  2858. BOOL VT_VECTOR_GT( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2859. {
  2860. return ! VT_VECTOR_LE( v1, v2 );
  2861. } //VT_VECTOR_GT
  2862. BOOL VT_VECTOR_GE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2863. {
  2864. return ! VT_VECTOR_LT( v1, v2 );
  2865. } //VT_VECTOR_GE
  2866. BOOL VT_VECTOR_EQ( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2867. {
  2868. return VT_VECTOR_Compare( v1, v2 ) == 0;
  2869. } //VT_VECTOR_EQ
  2870. BOOL VT_VECTOR_NE( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2871. {
  2872. return !VT_VECTOR_EQ( v1, v2 );
  2873. } //VT_VECTOR_NE
  2874. BOOL VT_VECTOR_Common(
  2875. PROPVARIANT const & v1,
  2876. PROPVARIANT const & v2,
  2877. ULONG relop )
  2878. {
  2879. // must be the same datatype and a vector or it doesn't compare.
  2880. if ( ( v1.vt != v2.vt ) || ! isVector( v1 ) )
  2881. return FALSE;
  2882. // must be same cardinality, or it doesn't compare
  2883. if ( v1.cal.cElems != v2.cal.cElems )
  2884. return FALSE;
  2885. FPRel cmp = VariantCompare.GetPointerRelop( v1, v2, relop );
  2886. if ( 0 == cmp )
  2887. return FALSE;
  2888. unsigned cElems = v1.cal.cElems;
  2889. for ( unsigned x = 0; x < cElems; x++ )
  2890. {
  2891. if ( !cmp( _GetNth( v1, x), _GetNth( v2, x ) ) )
  2892. return FALSE;
  2893. }
  2894. return TRUE;
  2895. } //VT_VECTOR_Common
  2896. BOOL VT_VECTOR_AllBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2897. {
  2898. return VT_VECTOR_Common( v1, v2, PRAllBits );
  2899. } //VT_VECTOR_AllBits
  2900. BOOL VT_VECTOR_SomeBits( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2901. {
  2902. return VT_VECTOR_Common( v1, v2, PRSomeBits );
  2903. } //VT_VECTOR_SomeBits
  2904. ////////////////////////////////////
  2905. ////////////////////////////////////
  2906. ////////////////////////////////////
  2907. BOOL VT_VECTOR_Any(
  2908. PROPVARIANT const & v1In,
  2909. PROPVARIANT const & v2In,
  2910. ULONG relop )
  2911. {
  2912. //
  2913. // Note: first parameter (v1) is the object's property value
  2914. // second parameter (v2) is the query restriction
  2915. //
  2916. // return TRUE if any element in v1 holds the relation to any v2 element
  2917. //
  2918. // base type of variant must be the same
  2919. if ( getBaseType( v1In ) != getBaseType( v2In ) )
  2920. return FALSE;
  2921. //
  2922. // If either argument is a safearray, convert it to a vector
  2923. //
  2924. PROPVARIANT v1 = v1In;
  2925. if (isArray(v1))
  2926. ConvertArrayToVector( v1In, v1 );
  2927. PROPVARIANT v2 = v2In;
  2928. if (isArray(v2))
  2929. ConvertArrayToVector( v2In, v2 );
  2930. // first check for two singletons
  2931. if ( ! isVector( v1 ) && ! isVector( v2 ) )
  2932. {
  2933. FRel cmp = VariantCompare.GetRelop( (VARENUM) v1.vt, relop );
  2934. if ( 0 == cmp )
  2935. return FALSE;
  2936. else
  2937. return cmp( v1, v2 );
  2938. }
  2939. // two vectors or singleton+vector -- get a pointer comparator
  2940. FPRel cmp = VariantCompare.GetPointerRelop( v1, v2, relop );
  2941. if ( 0 == cmp )
  2942. return FALSE;
  2943. // check for two vectors
  2944. if ( isVector( v1 ) && isVector( v2 ) )
  2945. {
  2946. for ( unsigned x1 = 0; x1 < v1.cal.cElems; x1++ )
  2947. {
  2948. for ( unsigned x2 = 0; x2 < v2.cal.cElems; x2++ )
  2949. {
  2950. if ( cmp( _GetNth( v1, x1), _GetNth( v2, x2 ) ) )
  2951. return TRUE;
  2952. }
  2953. }
  2954. }
  2955. else
  2956. {
  2957. // must be a singleton and a vector
  2958. if ( isVector( v1 ) )
  2959. {
  2960. BYTE * pb2 = (BYTE *) &(v2.lVal);
  2961. if ( VT_DECIMAL == v2.vt )
  2962. pb2 = (BYTE *) &(v2.decVal);
  2963. for ( unsigned i = 0; i < v1.cal.cElems; i++ )
  2964. {
  2965. if ( cmp( _GetNth( v1, i ), pb2 ) )
  2966. return TRUE;
  2967. }
  2968. }
  2969. else
  2970. {
  2971. BYTE * pb1 = (BYTE *) &(v1.lVal);
  2972. if ( VT_DECIMAL == v1.vt )
  2973. pb1 = (BYTE *) &(v1.decVal);
  2974. for ( unsigned i = 0; i < v2.cal.cElems; i++ )
  2975. {
  2976. if ( cmp( pb1, _GetNth( v2, i ) ) )
  2977. return TRUE;
  2978. }
  2979. }
  2980. }
  2981. return FALSE;
  2982. } //VT_VECTOR_Any
  2983. BOOL VT_VECTOR_LT_Any( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2984. {
  2985. return VT_VECTOR_Any( v1, v2, PRLT );
  2986. } //VT_VECTOR_LT_Any
  2987. BOOL VT_VECTOR_LE_Any( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2988. {
  2989. return VT_VECTOR_Any( v1, v2, PRLE );
  2990. } //VT_VECTOR_LE_Any
  2991. BOOL VT_VECTOR_GT_Any( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2992. {
  2993. return VT_VECTOR_Any( v1, v2, PRGT );
  2994. } //VT_VECTOR_GT_Any
  2995. BOOL VT_VECTOR_GE_Any( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  2996. {
  2997. return VT_VECTOR_Any( v1, v2, PRGE );
  2998. } //VT_VECTOR_GE_Any
  2999. BOOL VT_VECTOR_EQ_Any( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3000. {
  3001. return VT_VECTOR_Any( v1, v2, PREQ );
  3002. } //VT_VECTOR_EQ_Any
  3003. BOOL VT_VECTOR_NE_Any( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3004. {
  3005. return VT_VECTOR_Any( v1, v2, PRNE );
  3006. } //VT_VECTOR_NE_Any
  3007. BOOL VT_VECTOR_AllBits_Any( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3008. {
  3009. return VT_VECTOR_Any( v1, v2, PRAllBits );
  3010. } //VT_VECTOR_AllBits_Any
  3011. BOOL VT_VECTOR_SomeBits_Any( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3012. {
  3013. return VT_VECTOR_Any( v1, v2, PRSomeBits );
  3014. } //VT_VECTOR_SomeBits_Any
  3015. ////////////////////////////////////
  3016. ////////////////////////////////////
  3017. ////////////////////////////////////
  3018. BOOL VT_VECTOR_All(
  3019. PROPVARIANT const & v1In,
  3020. PROPVARIANT const & v2In,
  3021. ULONG relop )
  3022. {
  3023. //
  3024. // Note: first parameter (v1) is the object's property value
  3025. // second parameter (v2) is the query restriction
  3026. //
  3027. // each element in v2 must hold the relation to each element v1
  3028. // (not necessarily vice-versa)
  3029. //
  3030. // base type of variant must be the same
  3031. if ( getBaseType( v1In ) != getBaseType( v2In ) )
  3032. return FALSE;
  3033. //
  3034. // If either argument is a safearray, convert it to a vector
  3035. //
  3036. PROPVARIANT v1 = v1In;
  3037. if (isArray(v1))
  3038. ConvertArrayToVector( v1In, v1 );
  3039. PROPVARIANT v2 = v2In;
  3040. if (isArray(v2))
  3041. ConvertArrayToVector( v2In, v2 );
  3042. // first check for two singletons
  3043. if ( ! isVector( v1 ) && ! isVector( v2 ) )
  3044. {
  3045. FRel cmp = VariantCompare.GetRelop( (VARENUM) v1.vt, relop );
  3046. if ( 0 == cmp )
  3047. return FALSE;
  3048. else
  3049. return cmp( v1, v2 );
  3050. }
  3051. // two vectors or singleton+vector -- get a pointer comparator
  3052. FPRel cmp = VariantCompare.GetPointerRelop( v1, v2, relop );
  3053. if ( 0 == cmp )
  3054. return FALSE;
  3055. // check for two vectors
  3056. if ( isVector( v1 ) && isVector( v2 ) )
  3057. {
  3058. // Don't match empty vectors in queries.
  3059. if ( 0 == v2.cal.cElems )
  3060. return FALSE;
  3061. //
  3062. // Make sure the relation holds true for each element in the query
  3063. // paired with each element in the file's value.
  3064. //
  3065. for ( unsigned x2 = 0; x2 < v2.cal.cElems; x2++ )
  3066. {
  3067. for ( unsigned x1 = 0; x1 < v1.cal.cElems; x1++ )
  3068. {
  3069. if ( ! cmp( _GetNth( v1, x1), _GetNth( v2, x2 ) ) )
  3070. return FALSE;
  3071. }
  3072. }
  3073. }
  3074. else
  3075. {
  3076. // must be a singleton and a vector
  3077. if ( isVector( v1 ) )
  3078. {
  3079. BYTE * pb2 = (BYTE *) &(v2.lVal);
  3080. if ( VT_DECIMAL == v2.vt )
  3081. pb2 = (BYTE *) &(v2.decVal);
  3082. for ( unsigned i = 0; i < v1.cal.cElems; i++ )
  3083. {
  3084. if ( ! cmp( _GetNth( v1, i ), pb2 ) )
  3085. return FALSE;
  3086. }
  3087. }
  3088. else
  3089. {
  3090. BYTE * pb1 = (BYTE *) &(v1.lVal);
  3091. if ( VT_DECIMAL == v1.vt )
  3092. pb1 = (BYTE *) &(v1.decVal);
  3093. for ( unsigned i = 0; i < v2.cal.cElems; i++ )
  3094. {
  3095. if ( ! cmp( pb1, _GetNth( v2, i ) ) )
  3096. return FALSE;
  3097. }
  3098. }
  3099. }
  3100. return TRUE;
  3101. } //VT_VECTOR_All
  3102. BOOL VT_VECTOR_LT_All( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3103. {
  3104. return VT_VECTOR_All( v1, v2, PRLT );
  3105. } //VT_VECTOR_LT_All
  3106. BOOL VT_VECTOR_LE_All( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3107. {
  3108. return VT_VECTOR_All( v1, v2, PRLE );
  3109. } //VT_VECTOR_LE_All
  3110. BOOL VT_VECTOR_GT_All( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3111. {
  3112. return VT_VECTOR_All( v1, v2, PRGT );
  3113. } //VT_VECTOR_GT_All
  3114. BOOL VT_VECTOR_GE_All( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3115. {
  3116. return VT_VECTOR_All( v1, v2, PRGE );
  3117. } //VT_VECTOR_GE_All
  3118. BOOL VT_VECTOR_EQ_All( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3119. {
  3120. return VT_VECTOR_All( v1, v2, PREQ );
  3121. } //VT_VECTOR_EQ_All
  3122. BOOL VT_VECTOR_NE_All( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3123. {
  3124. return VT_VECTOR_All( v1, v2, PRNE );
  3125. } //VT_VECTOR_NE_All
  3126. BOOL VT_VECTOR_AllBits_All( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3127. {
  3128. return VT_VECTOR_All( v1, v2, PRAllBits );
  3129. } //VT_VECTOR_AllBits_All
  3130. BOOL VT_VECTOR_SomeBits_All( PROPVARIANT const & v1, PROPVARIANT const & v2 )
  3131. {
  3132. return VT_VECTOR_All( v1, v2, PRSomeBits );
  3133. } //VT_VECTOR_SomeBits_All
  3134. ////////////////////////////////////
  3135. ////////////////////////////////////
  3136. ////////////////////////////////////
  3137. FRel const CComparators::_aVectorComparators[] =
  3138. {
  3139. VT_VECTOR_LT,
  3140. VT_VECTOR_LE,
  3141. VT_VECTOR_GT,
  3142. VT_VECTOR_GE,
  3143. VT_VECTOR_EQ,
  3144. VT_VECTOR_NE,
  3145. 0,
  3146. VT_VECTOR_AllBits,
  3147. VT_VECTOR_SomeBits
  3148. };
  3149. ULONG const CComparators::_cVectorComparators =
  3150. sizeof CComparators::_aVectorComparators /
  3151. sizeof CComparators::_aVectorComparators[0];
  3152. FRel const CComparators::_aVectorComparatorsAll[] =
  3153. {
  3154. VT_VECTOR_LT_All,
  3155. VT_VECTOR_LE_All,
  3156. VT_VECTOR_GT_All,
  3157. VT_VECTOR_GE_All,
  3158. VT_VECTOR_EQ_All,
  3159. VT_VECTOR_NE_All,
  3160. 0,
  3161. VT_VECTOR_AllBits_All,
  3162. VT_VECTOR_SomeBits_All
  3163. };
  3164. ULONG const CComparators::_cVectorComparatorsAll =
  3165. sizeof CComparators::_aVectorComparatorsAll /
  3166. sizeof CComparators::_aVectorComparatorsAll[0];
  3167. FRel const CComparators::_aVectorComparatorsAny[] =
  3168. {
  3169. VT_VECTOR_LT_Any,
  3170. VT_VECTOR_LE_Any,
  3171. VT_VECTOR_GT_Any,
  3172. VT_VECTOR_GE_Any,
  3173. VT_VECTOR_EQ_Any,
  3174. VT_VECTOR_NE_Any,
  3175. 0,
  3176. VT_VECTOR_AllBits_Any,
  3177. VT_VECTOR_SomeBits_Any
  3178. };
  3179. ULONG const CComparators::_cVectorComparatorsAny =
  3180. sizeof CComparators::_aVectorComparatorsAny /
  3181. sizeof CComparators::_aVectorComparatorsAny[0];
  3182. ////////////////////////////////////
  3183. ////////////////////////////////////
  3184. ////////////////////////////////////
  3185. FCmp CComparators::GetComparator( VARENUM vt )
  3186. {
  3187. if ( isVectorOrArray( vt ) )
  3188. {
  3189. return VT_VECTOR_Compare;
  3190. }
  3191. else if ( vt >= _iStart && vt < _iStart + _cVariantComparators )
  3192. {
  3193. return( _aVariantComparators[vt].comparator );
  3194. }
  3195. else if ( vt >= _iStart2 && vt < _iStart2 + _cVariantComparators2 )
  3196. {
  3197. return( _aVariantComparators2[vt - _iStart2].comparator );
  3198. }
  3199. else if ( vt >= _iStart3 && vt < _iStart3 + _cVariantComparators3 )
  3200. {
  3201. return( _aVariantComparators3[vt - _iStart3].comparator );
  3202. }
  3203. else
  3204. {
  3205. ciDebugOut(( DEB_ERROR,
  3206. "CComparators::GetComparator Unknown property type %d in comparison.\n",
  3207. vt ));
  3208. Win4Assert( !"Unknown property type used in comparison." );
  3209. return( 0 );
  3210. }
  3211. } //GetComparator
  3212. FRel CComparators::GetRelop( VARENUM vt, ULONG relop )
  3213. {
  3214. if ( ( ( isVectorOrArray( vt ) ) ||
  3215. ( isVectorRelop( relop ) ) ) &&
  3216. ( getBaseRelop( relop ) < _cVectorComparators ) )
  3217. {
  3218. if ( isRelopAny( relop ) )
  3219. return _aVectorComparatorsAny[ getBaseRelop( relop ) ];
  3220. else if ( isRelopAll( relop ) )
  3221. return _aVectorComparatorsAll[ getBaseRelop( relop ) ];
  3222. else
  3223. return _aVectorComparators[ relop ];
  3224. }
  3225. else if ( vt >= _iStart && vt < _cVariantComparators &&
  3226. relop < sizeof(_aVariantComparators[0].relops)/
  3227. sizeof(_aVariantComparators[0].relops[0] ) )
  3228. {
  3229. return( _aVariantComparators[vt].relops[relop] );
  3230. }
  3231. else if ( vt >= _iStart2 && vt < _iStart2 + _cVariantComparators2 &&
  3232. relop < sizeof(_aVariantComparators2[0].relops)/
  3233. sizeof(_aVariantComparators2[0].relops[0] ) )
  3234. {
  3235. return( _aVariantComparators2[vt - _iStart2].relops[relop] );
  3236. }
  3237. else if ( vt >= _iStart3 && vt < _iStart3 + _cVariantComparators3 &&
  3238. relop < sizeof(_aVariantComparators3[0].relops)/
  3239. sizeof(_aVariantComparators3[0].relops[0] ) )
  3240. {
  3241. return( _aVariantComparators3[vt - _iStart3].relops[relop] );
  3242. }
  3243. else
  3244. {
  3245. ciDebugOut(( DEB_ERROR,
  3246. "CComparators::GetRelop Unknown property type %d or relation %d used in comparison.\n",
  3247. vt, relop ));
  3248. Win4Assert( !"Unknown property type or relop used in comparison." );
  3249. return( 0 );
  3250. }
  3251. } //GetRelop
  3252. FPCmp CComparators::GetPointerComparator(
  3253. PROPVARIANT const & v1,
  3254. PROPVARIANT const & v2 )
  3255. {
  3256. VARENUM vt = getBaseType( v1 );
  3257. if ( VT_CLSID == vt )
  3258. {
  3259. // GUIDs are the only case of variants where the data inside
  3260. // a singleton is different from an element in a vector.
  3261. // Data in a singleton is a pointer to a guid.
  3262. // Data in the element of a vector is the guid itself.
  3263. // The vector compare code assumes that the layout of singletons
  3264. // and vectors is the same, so we need special-case comparators
  3265. // for GUIDs.
  3266. if ( isVector( v1 ) && isVector( v2 ) )
  3267. return VTP_VV_CLSID_Compare;
  3268. else if ( isVector( v1 ) )
  3269. return VTP_VS_CLSID_Compare;
  3270. else if ( isVector( v2 ) )
  3271. return VTP_SV_CLSID_Compare;
  3272. else
  3273. return VTP_SS_CLSID_Compare;
  3274. Win4Assert( !"unanticipated clsid / vector code path" );
  3275. }
  3276. if ( vt >= _iStart && vt < _iStart + _cVariantComparators )
  3277. return( _aVariantComparators[vt].pointercomparator );
  3278. else if ( vt >= _iStart2 && vt < _iStart2 + _cVariantComparators2 )
  3279. return( _aVariantComparators2[vt - _iStart2].pointercomparator );
  3280. else if ( vt >= _iStart3 && vt < _iStart3 + _cVariantComparators3 )
  3281. return( _aVariantComparators3[vt - _iStart3].pointercomparator );
  3282. else
  3283. {
  3284. ciDebugOut(( DEB_ERROR,
  3285. "CComparators::GetPointerComparator Unknown property type %d in comparison.\n",
  3286. vt ));
  3287. Win4Assert( !"Unknown property type used in pointer comparison." );
  3288. return( 0 );
  3289. }
  3290. } //GetPointerComparator
  3291. FPRel CComparators::GetPointerRelop(
  3292. PROPVARIANT const & v1,
  3293. PROPVARIANT const & v2,
  3294. ULONG relop )
  3295. {
  3296. VARENUM vt = getBaseType( v1 );
  3297. if ( VT_CLSID == vt )
  3298. {
  3299. // GUIDs are the only case of variants where the data inside
  3300. // a singleton is different from an element in a vector.
  3301. // Data in a singleton is a pointer to a guid.
  3302. // Data in the element of a vector is the guid itself.
  3303. // The vector compare code assumes that the layout of singletons
  3304. // and vectors is the same, so we need special-case comparators
  3305. // for GUIDs.
  3306. if ( isVector( v1 ) && isVector( v2 ) )
  3307. {
  3308. if ( PREQ == relop )
  3309. return VTP_VV_CLSID_EQ;
  3310. else if ( PRNE == relop )
  3311. return VTP_VV_CLSID_NE;
  3312. else
  3313. return 0;
  3314. }
  3315. else if ( isVector( v1 ) )
  3316. {
  3317. if ( PREQ == relop )
  3318. return VTP_VS_CLSID_EQ;
  3319. else if ( PRNE == relop )
  3320. return VTP_VS_CLSID_NE;
  3321. else
  3322. return 0;
  3323. }
  3324. else if ( isVector( v2 ) )
  3325. {
  3326. if ( PREQ == relop )
  3327. return VTP_SV_CLSID_EQ;
  3328. else if ( PRNE == relop )
  3329. return VTP_SV_CLSID_NE;
  3330. else
  3331. return 0;
  3332. }
  3333. else
  3334. {
  3335. if ( PREQ == relop )
  3336. return VTP_SS_CLSID_EQ;
  3337. else if ( PRNE == relop )
  3338. return VTP_SS_CLSID_NE;
  3339. else
  3340. return 0;
  3341. }
  3342. }
  3343. if ( vt >= _iStart && vt < _cVariantComparators &&
  3344. relop < sizeof(_aVariantComparators[0].pointerrelops)/
  3345. sizeof(_aVariantComparators[0].pointerrelops[0] ) )
  3346. return( _aVariantComparators[vt].pointerrelops[relop] );
  3347. else if ( vt >= _iStart2 && vt < _iStart2 + _cVariantComparators2 &&
  3348. relop < sizeof(_aVariantComparators2[0].pointerrelops)/
  3349. sizeof(_aVariantComparators2[0].pointerrelops[0] ) )
  3350. return( _aVariantComparators2[vt - _iStart2].pointerrelops[relop] );
  3351. else if ( vt >= _iStart3 && vt < _iStart3 + _cVariantComparators3 &&
  3352. relop < sizeof(_aVariantComparators3[0].pointerrelops)/
  3353. sizeof(_aVariantComparators3[0].pointerrelops[0] ) )
  3354. return( _aVariantComparators3[vt - _iStart3].pointerrelops[relop] );
  3355. else
  3356. {
  3357. ciDebugOut(( DEB_ERROR,
  3358. "CComparators::GetPointerRelop Unknown property type %d or relation %d used in comparison.\n",
  3359. vt, relop ));
  3360. Win4Assert( !"Unknown property type or relop used in pointer comparison." );
  3361. return( 0 );
  3362. }
  3363. } //GetPointerRelop
  3364. ////////////////////////////////////////////////////////////////////////
  3365. ////////////////////////////////////////////////////////////////////////
  3366. ////////////////////////////////////////////////////////////////////////
  3367. ////////////////////////////////////////////////////////////////////////
  3368. ////////////////////////////////////////////////////////////////////////
  3369. ////////////////////////////////////////////////////////////////////////
  3370. ////////////////////////////////////////////////////////////////////////
  3371. ////////////////////////////////////////////////////////////////////////
  3372. ////////////////////////////////////////////////////////////////////////
  3373. int DBVector_Compare( DBTYPEENUM type, BYTE const * p1, BYTE const * p2 )
  3374. {
  3375. //
  3376. // Convert to variants and use the normal variant vector comparator.
  3377. // This is a little bit slow, but it is an odd case and the code size
  3378. // otherwise would be greatly increased.
  3379. //
  3380. PROPVARIANT v1,v2;
  3381. Win4Assert( isVector(type) );
  3382. v1.vt = v2.vt = (VARENUM) type;
  3383. v1.cal = *(CAL *) p1;
  3384. v2.cal = *(CAL *) p2;
  3385. return VT_VECTOR_Compare( v1, v2 );
  3386. } //DBVector_Compare
  3387. int DBTYPE_EMPTY_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3388. {
  3389. return( 0 );
  3390. }
  3391. int DBTYPE_NULL_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3392. {
  3393. return( 0 );
  3394. }
  3395. int DBTYPE_I1_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3396. {
  3397. return( *(signed char *)pv1 - *(signed char *)pv2 );
  3398. }
  3399. int DBTYPE_I1_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3400. {
  3401. return DBVector_Compare( dbVector( DBTYPE_I1 ), pv1, pv2);
  3402. }
  3403. int DBTYPE_UI1_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3404. {
  3405. return( *(unsigned char *)pv1 - *(unsigned char *)pv2 );
  3406. }
  3407. int DBTYPE_UI1_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3408. {
  3409. return DBVector_Compare( dbVector( DBTYPE_UI1 ), pv1, pv2);
  3410. }
  3411. int DBTYPE_I2_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3412. {
  3413. return( *(short *)pv1 - *(short *)pv2 );
  3414. }
  3415. int DBTYPE_I2_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3416. {
  3417. return DBVector_Compare( dbVector( DBTYPE_I2 ), pv1, pv2);
  3418. }
  3419. int DBTYPE_UI2_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3420. {
  3421. return( *(unsigned short *)pv1 - *(unsigned short *)pv2 );
  3422. }
  3423. int DBTYPE_UI2_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3424. {
  3425. return DBVector_Compare( dbVector( DBTYPE_UI2 ), pv1, pv2);
  3426. }
  3427. int DBTYPE_I4_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3428. {
  3429. long l1 = * (long *) pv1;
  3430. long l2 = * (long *) pv2;
  3431. return ( l1 > l2 ) ? 1 : ( l1 < l2 ) ? -1 : 0;
  3432. }
  3433. int DBTYPE_I4_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3434. {
  3435. return DBVector_Compare( dbVector( DBTYPE_I4 ), pv1, pv2);
  3436. }
  3437. int DBTYPE_UI4_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3438. {
  3439. ULONG ul1 = * (ULONG *) pv1;
  3440. ULONG ul2 = * (ULONG *) pv2;
  3441. return ( ul1 > ul2 ) ? 1 : ( ul1 < ul2 ) ? -1 : 0;
  3442. }
  3443. int DBTYPE_UI4_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3444. {
  3445. return DBVector_Compare( dbVector( DBTYPE_UI4 ), pv1, pv2);
  3446. }
  3447. int DBTYPE_R4_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3448. {
  3449. return VTP_R4_Compare( pv1, pv2 );
  3450. }
  3451. int DBTYPE_R4_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3452. {
  3453. return DBVector_Compare( dbVector( DBTYPE_R4 ), pv1, pv2);
  3454. }
  3455. int DBTYPE_R8_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3456. {
  3457. return VTP_R8_Compare( pv1, pv2 );
  3458. }
  3459. int DBTYPE_R8_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3460. {
  3461. return DBVector_Compare( dbVector( DBTYPE_R8 ), pv1, pv2);
  3462. }
  3463. int DBTYPE_I8_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3464. {
  3465. return( *(LONGLONG *)pv1 > *(LONGLONG *)pv2 ? 1 :
  3466. *(LONGLONG *)pv1 == *(LONGLONG *)pv2 ? 0 :
  3467. -1 );
  3468. }
  3469. int DBTYPE_I8_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3470. {
  3471. return DBVector_Compare( dbVector( DBTYPE_I8 ), pv1, pv2);
  3472. }
  3473. int DBTYPE_UI8_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3474. {
  3475. return( *(ULONGLONG *)pv1 > *(ULONGLONG *)pv2 ? 1 :
  3476. *(ULONGLONG *)pv1 == *(ULONGLONG *)pv2 ? 0 :
  3477. -1 );
  3478. }
  3479. int DBTYPE_UI8_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3480. {
  3481. return DBVector_Compare( dbVector( DBTYPE_UI8 ), pv1, pv2);
  3482. }
  3483. int DBTYPE_BOOL_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3484. {
  3485. return( (*(USHORT *)pv1 == 0) == (*(USHORT *)pv2 == 0) );
  3486. }
  3487. int DBTYPE_BOOL_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3488. {
  3489. return DBVector_Compare( dbVector( DBTYPE_BOOL ), pv1, pv2);
  3490. }
  3491. int DBTYPE_VARIANT_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3492. {
  3493. return VT_VARIANT_Compare( * (PROPVARIANT *) pv1, * (PROPVARIANT *) pv2 );
  3494. }
  3495. int DBTYPE_GUID_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3496. {
  3497. return( memcmp( pv1, pv2, sizeof(GUID) ) );
  3498. }
  3499. int DBTYPE_GUID_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3500. {
  3501. return DBVector_Compare( dbVector( DBTYPE_GUID ), pv1, pv2);
  3502. }
  3503. int DBTYPE_BYTES_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3504. {
  3505. ULONG mincb = __min( cb1, cb2 );
  3506. int result = memcmp( pv1, pv2, mincb );
  3507. if (result == 0)
  3508. result = cb1 - cb2;
  3509. return result;
  3510. }
  3511. int DBTYPE_STR_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3512. {
  3513. int cMin = __min( cb1, cb2 );
  3514. int ret = _strnicmp( (char *) pv1, (char *) pv2, cMin );
  3515. if (0 == ret)
  3516. return cb1 - cb2;
  3517. else
  3518. return ret;
  3519. }
  3520. int DBTYPE_WSTR_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3521. {
  3522. int cMin = __min( cb1, cb2 );
  3523. int ret = _wcsnicmp( (WCHAR *) pv1, (WCHAR *) pv2, cMin );
  3524. if (0 == ret)
  3525. return cb1 - cb2;
  3526. else
  3527. return ret;
  3528. }
  3529. int DBTYPE_BSTR_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3530. {
  3531. return VTP_BSTR_Compare( pv1, pv2 );
  3532. }
  3533. int DBTYPE_BSTR_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3534. {
  3535. return DBVector_Compare( dbVector( (DBTYPEENUM) VT_BSTR ), pv1, pv2);
  3536. }
  3537. int DBTYPE_LPSTR_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3538. {
  3539. return _stricmp( (*(char **) pv1), (*(char **) pv2) );
  3540. }
  3541. int DBTYPE_LPSTR_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3542. {
  3543. return DBVector_Compare( dbVector( (DBTYPEENUM) VT_LPSTR ), pv1, pv2);
  3544. }
  3545. int DBTYPE_LPWSTR_Compare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3546. {
  3547. int rc = CompareStringW( LOCALE_SYSTEM_DEFAULT,
  3548. NORM_IGNORECASE,
  3549. (*(WCHAR **) pv1),
  3550. -1,
  3551. (*(WCHAR **) pv2),
  3552. -1 );
  3553. //
  3554. // rc == 1, means less than
  3555. // rc == 2, means equal
  3556. // rc == 3, means greater than
  3557. //
  3558. return rc - 2;
  3559. }
  3560. int DBTYPE_LPWSTR_VectorCompare( BYTE const * pv1, ULONG cb1, BYTE const * pv2, ULONG cb2 )
  3561. {
  3562. return DBVector_Compare( dbVector( (DBTYPEENUM) VT_LPWSTR ), pv1, pv2);
  3563. }
  3564. CComparators::SDBComparators const CComparators::_aDBComparators[] = {
  3565. // VT_EMPTY, DBTYPE_EMPTY
  3566. { DBTYPE_EMPTY_Compare,
  3567. 0,
  3568. },
  3569. // VT_NULL, DBTYPE_NULL
  3570. { DBTYPE_NULL_Compare,
  3571. 0,
  3572. },
  3573. // VT_I2, DBTYPE_I2
  3574. { DBTYPE_I2_Compare,
  3575. DBTYPE_I2_VectorCompare,
  3576. },
  3577. // VT_I4, DBTYPE_I4
  3578. { DBTYPE_I4_Compare,
  3579. DBTYPE_I4_VectorCompare,
  3580. },
  3581. // VT_R4, DBTYPE_R4
  3582. { DBTYPE_R4_Compare,
  3583. DBTYPE_R4_VectorCompare,
  3584. },
  3585. // VT_R8, DBTYPE_R8
  3586. { DBTYPE_R8_Compare,
  3587. DBTYPE_R8_VectorCompare,
  3588. },
  3589. // VT_CY, DBTYPE_CY
  3590. { DBTYPE_I8_Compare,
  3591. DBTYPE_I8_VectorCompare,
  3592. },
  3593. // VT_DATE, DBTYPE_DATE
  3594. { DBTYPE_R8_Compare,
  3595. DBTYPE_R8_VectorCompare,
  3596. },
  3597. // VT_BSTR, DBTYPE_BSTR
  3598. { DBTYPE_BSTR_Compare,
  3599. DBTYPE_BSTR_VectorCompare,
  3600. },
  3601. // VT_DISPATCH
  3602. { 0,
  3603. 0,
  3604. },
  3605. // VT_ERROR
  3606. { DBTYPE_I4_Compare,
  3607. DBTYPE_I4_VectorCompare,
  3608. },
  3609. // VT_BOOL
  3610. { DBTYPE_BOOL_Compare,
  3611. DBTYPE_BOOL_VectorCompare,
  3612. },
  3613. // VT_VARIANT
  3614. { DBTYPE_VARIANT_Compare,
  3615. DBTYPE_VARIANT_Compare,
  3616. },
  3617. // VT_UNKNOWN
  3618. { 0,
  3619. 0,
  3620. },
  3621. // VARENUM value 14 unused
  3622. { 0,
  3623. 0,
  3624. },
  3625. // VARENUM value 15 unused
  3626. { 0,
  3627. 0,
  3628. },
  3629. // VT_I1 undefined in PROPVARIANT union
  3630. { DBTYPE_I1_Compare,
  3631. DBTYPE_I1_VectorCompare,
  3632. },
  3633. // VT_UI1
  3634. { DBTYPE_UI1_Compare,
  3635. DBTYPE_UI1_VectorCompare,
  3636. },
  3637. // VT_UI2
  3638. { DBTYPE_UI2_Compare,
  3639. DBTYPE_UI2_VectorCompare,
  3640. },
  3641. // VT_UI4
  3642. { DBTYPE_UI4_Compare,
  3643. DBTYPE_UI4_VectorCompare,
  3644. },
  3645. // VT_I8
  3646. { DBTYPE_I8_Compare,
  3647. DBTYPE_I8_VectorCompare,
  3648. },
  3649. // VT_UI8
  3650. { DBTYPE_UI8_Compare,
  3651. DBTYPE_UI8_VectorCompare,
  3652. },
  3653. // VT_INT undefined in PROPVARIANT union
  3654. { 0,
  3655. 0,
  3656. },
  3657. // VT_UINT undefined in PROPVARIANT union
  3658. { 0,
  3659. 0,
  3660. },
  3661. // VT_VOID
  3662. { 0,
  3663. 0,
  3664. },
  3665. // VT_HRESULT
  3666. { 0,
  3667. 0,
  3668. },
  3669. // VT_PTR
  3670. { 0,
  3671. 0,
  3672. },
  3673. // VT_SAFEARRAY
  3674. { 0,
  3675. 0,
  3676. },
  3677. // VT_CARRAY
  3678. { 0,
  3679. 0,
  3680. },
  3681. // VT_USERDEFINED
  3682. { 0,
  3683. 0,
  3684. },
  3685. // VT_LPSTR (translated form of DBTYPE_STR | DBTYPE_BYREF)
  3686. { DBTYPE_LPSTR_Compare,
  3687. DBTYPE_LPSTR_VectorCompare,
  3688. },
  3689. // VT_LPWSTR (translated form of DBTYPE_WSTR | DBTYPE_BYREF)
  3690. { DBTYPE_LPWSTR_Compare,
  3691. DBTYPE_LPWSTR_VectorCompare,
  3692. }
  3693. };
  3694. ULONG const CComparators::_iDBStart = VT_EMPTY;
  3695. ULONG const CComparators::_cDBComparators =
  3696. sizeof(CComparators::_aDBComparators) /
  3697. sizeof(CComparators::_aDBComparators[0]);
  3698. ULONG const CComparators::_iDBStart2 = VT_FILETIME;
  3699. CComparators::SDBComparators const CComparators::_aDBComparators2[] = {
  3700. // VT_FILETIME
  3701. { DBTYPE_UI8_Compare,
  3702. DBTYPE_UI8_VectorCompare,
  3703. },
  3704. // VT_BLOB
  3705. { 0,
  3706. 0,
  3707. },
  3708. // VT_STREAM
  3709. { 0,
  3710. 0,
  3711. },
  3712. // VT_STORAGE
  3713. { 0,
  3714. 0,
  3715. },
  3716. // VT_STREAMED_OBJECT
  3717. { 0,
  3718. 0,
  3719. },
  3720. // VT_STORED_OBJECT
  3721. { 0,
  3722. 0,
  3723. },
  3724. // VT_BLOB_OBJECT
  3725. { 0,
  3726. 0,
  3727. },
  3728. // VT_CF
  3729. { 0,
  3730. 0,
  3731. },
  3732. // VT_CLSID, DBTYPE_GUID
  3733. { DBTYPE_GUID_Compare,
  3734. DBTYPE_GUID_VectorCompare,
  3735. }
  3736. };
  3737. ULONG const CComparators::_cDBComparators2 =
  3738. sizeof(CComparators::_aDBComparators2) /
  3739. sizeof(CComparators::_aDBComparators2[0]);
  3740. ULONG const CComparators::_iDBStart3 = DBTYPE_BYTES;
  3741. CComparators::SDBComparators const CComparators::_aDBComparators3[] = {
  3742. // DBTYPE_BYTES
  3743. { DBTYPE_BYTES_Compare,
  3744. 0,
  3745. },
  3746. // DBTYPE_STR
  3747. { DBTYPE_STR_Compare,
  3748. 0,
  3749. },
  3750. // DBTYPE_WSTR
  3751. { DBTYPE_WSTR_Compare,
  3752. 0,
  3753. }
  3754. };
  3755. ULONG const CComparators::_cDBComparators3 =
  3756. sizeof(CComparators::_aDBComparators3) /
  3757. sizeof(CComparators::_aDBComparators3[0]);
  3758. //+-------------------------------------------------------------------------
  3759. //
  3760. // Member: CComparators::_RationalizeDBByRef, private
  3761. //
  3762. // Synopsis: Converts BYREF oledb string types to variant equivalents
  3763. //
  3764. // Arguments: [vt] -- Data type to be converted.
  3765. //
  3766. // Returns: A VARENUM equivalent for oledb string types
  3767. //
  3768. // Notes: DBTYPE_BYREF | DBTYPE_WSTR and the vector version of the
  3769. // same are idential in meaning to the corresponding VT_LPWSTR
  3770. // VARENUM type.
  3771. //
  3772. // History: 25-May-95 dlee Created
  3773. //
  3774. //--------------------------------------------------------------------------
  3775. DBTYPEENUM CComparators::_RationalizeDBByRef( DBTYPEENUM vt )
  3776. {
  3777. // convert these types to something usable as an index
  3778. if ( 0 != ( DBTYPE_BYREF & vt ) )
  3779. {
  3780. if ( (DBTYPE_BYREF | DBTYPE_WSTR) == vt )
  3781. return (DBTYPEENUM) VT_LPWSTR;
  3782. else if ( (DBTYPE_BYREF | DBTYPE_STR) == vt )
  3783. return (DBTYPEENUM) VT_LPSTR;
  3784. if ( (DBTYPE_VECTOR | DBTYPE_BYREF | DBTYPE_WSTR) == vt )
  3785. return (DBTYPEENUM) (VT_VECTOR | VT_LPWSTR);
  3786. else if ( (DBTYPE_VECTOR | DBTYPE_BYREF | DBTYPE_STR) == vt )
  3787. return (DBTYPEENUM) (VT_VECTOR | VT_LPSTR);
  3788. }
  3789. return vt;
  3790. } //_RationalizeByRef
  3791. //+-------------------------------------------------------------------------
  3792. //
  3793. // Member: CComparators::GetDBComparator, public
  3794. //
  3795. // Synopsis: Returns a comparison function for a given data type.
  3796. //
  3797. // Arguments: [vt] -- Data type of returned comparator.
  3798. //
  3799. // Returns: Pointer to an FDBCmp function
  3800. //
  3801. // History: 25-May-95 dlee Created
  3802. //
  3803. //--------------------------------------------------------------------------
  3804. FDBCmp CComparators::GetDBComparator( DBTYPEENUM vt )
  3805. {
  3806. vt = _RationalizeDBByRef( vt );
  3807. if ( 0 != ( DBTYPE_VECTOR & vt ) )
  3808. {
  3809. vt = (DBTYPEENUM) ( vt & ( ~ DBTYPE_VECTOR ) );
  3810. if ( vt >= _iDBStart && vt < _iDBStart + _cDBComparators )
  3811. {
  3812. return( _aDBComparators[vt].dbvectorcomparator );
  3813. }
  3814. else if ( vt >= _iDBStart2 && vt < _iDBStart2 + _cDBComparators2 )
  3815. {
  3816. return( _aDBComparators2[vt - _iDBStart2].dbvectorcomparator );
  3817. }
  3818. else if ( vt >= _iDBStart3 && vt < _iDBStart3 + _cDBComparators3 )
  3819. {
  3820. return( _aDBComparators3[vt - _iDBStart3].dbvectorcomparator );
  3821. }
  3822. else
  3823. {
  3824. ciDebugOut(( DEB_ERROR,
  3825. "CComparators::GetDBComparator Unknown property type %d in comparison.\n",
  3826. vt ));
  3827. Win4Assert( !"Unknown property type used in comparison." );
  3828. return( 0 );
  3829. }
  3830. }
  3831. else if ( vt >= _iDBStart && vt < _iDBStart + _cDBComparators )
  3832. {
  3833. return( _aDBComparators[vt].dbcomparator );
  3834. }
  3835. else if ( vt >= _iDBStart2 && vt < _iDBStart2 + _cDBComparators2 )
  3836. {
  3837. return( _aDBComparators2[vt - _iDBStart2].dbcomparator );
  3838. }
  3839. else if ( vt >= _iDBStart3 && vt < _iDBStart3 + _cDBComparators3 )
  3840. {
  3841. return( _aDBComparators3[vt - _iDBStart3].dbcomparator );
  3842. }
  3843. else
  3844. {
  3845. // This will be hit if someone has a binding like
  3846. // DBTYPE_I2 | DBTYPE_BYREF, which means that instead
  3847. // of writing 2 bytes into their data, we allocate 2
  3848. // bytes from OLE and write that pointer into 4 bytes
  3849. // of the client data. There is a bug against oledb
  3850. // to not allow the client to do something so ill-advised.
  3851. //
  3852. ciDebugOut(( DEB_ERROR,
  3853. "CComparators::GetDBComparator Unknown property type %d in comparison.\n",
  3854. vt ));
  3855. Win4Assert( !"Unknown property type used in comparison." );
  3856. return( 0 );
  3857. }
  3858. } //GetDBComparator