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.

262 lines
6.6 KiB

  1. /*
  2. * MAPI 1.0 property handling routines
  3. *
  4. * RK.C -
  5. *
  6. * Two Rabin/Karp string finding functions
  7. * The two are almost identical.
  8. */
  9. #include "_apipch.h"
  10. #define ulPrime ((ULONG) 0x00FF00F1)
  11. #define ulBase ((ULONG) 0x00000100)
  12. BOOL FRKFindSubpb(LPBYTE pbTarget, ULONG cbTarget,
  13. LPBYTE pbPattern, ULONG cbPattern)
  14. {
  15. UINT i;
  16. LPBYTE pbTargetMax = pbTarget + cbTarget;
  17. LPBYTE pbPatternMax = pbPattern + cbPattern;
  18. ULONG ulBaseToPowerMod = 1;
  19. ULONG ulHashPattern = 0;
  20. ULONG ulHashTarget = 0;
  21. if (cbPattern > cbTarget)
  22. return FALSE;
  23. // Compute the power of the left most character in base ulBase
  24. for (i = 1; i < cbPattern; i++)
  25. ulBaseToPowerMod = (ulBase * ulBaseToPowerMod) % ulPrime;
  26. // Calculate the hash function for the src (and the first dst)
  27. while (pbPattern < pbPatternMax)
  28. {
  29. ulHashPattern = (ulHashPattern*ulBase+*pbPattern) % ulPrime;
  30. ulHashTarget = (ulHashTarget*ulBase+*pbTarget) % ulPrime;
  31. pbPattern++;
  32. pbTarget++;
  33. }
  34. // Dynamically produce hash values for the string as we go
  35. for ( ;; )
  36. {
  37. // Remember to do the memcmp for the off-chance it doesn't work
  38. // according to probability
  39. if ( ulHashPattern == ulHashTarget
  40. && !memcmp(pbPattern-cbPattern, pbTarget-cbPattern,
  41. (UINT)cbPattern))
  42. return TRUE;
  43. // Assert because this is very unprobable
  44. #ifdef DEBUG
  45. if (ulHashPattern == ulHashTarget)
  46. DebugTrace( TEXT("This is very unprobable!\n"));
  47. #endif
  48. if (pbTarget == pbTargetMax)
  49. return FALSE;
  50. ulHashTarget = (ulHashTarget+ulBase*ulPrime-
  51. *(pbTarget-cbPattern)*ulBaseToPowerMod) % ulPrime;
  52. ulHashTarget = (ulHashTarget*ulBase+*pbTarget) % ulPrime;
  53. pbTarget++;
  54. }
  55. }
  56. // Note - 4/14/97
  57. // Replaced FGLeadByte() with IsDBCSLeadByte()
  58. LPSTR LpszRKFindSubpsz(LPSTR pszTarget, ULONG cbTarget, LPSTR pszPattern,
  59. ULONG cbPattern, ULONG ulFuzzyLevel)
  60. {
  61. #ifdef OLDSTUFF_DBCS
  62. LCID lcid = GetUserDefaultLCID();
  63. LANGID langID = LANGIDFROMLCID(lcid);
  64. LPBYTE pbTarget;
  65. LPBYTE pbPattern;
  66. BOOL fResult = FALSE;
  67. ULONG ulchPattern; // cbPattern in character unit.
  68. ULONG ulcbTarget = cbTarget;
  69. ULONG ulcbEndTarget; // = cbPattern at the end of pszTarget
  70. const ULONG ulCharType = UlGCharType(pszPattern);
  71. pbTarget = (LPBYTE) pszTarget;
  72. pbPattern = (LPBYTE) pszPattern;
  73. ulchPattern = ulchStrCount(pbPattern, cbPattern, langID);
  74. ulcbEndTarget = ulcbEndCount(pbTarget, cbTarget, ulchPattern, langID);
  75. if (ulcbEndTarget == 0)
  76. goto end;
  77. while(ulcbEndTarget <= ulcbTarget)
  78. {
  79. const BOOL fTargetDBCS = IsDBCSLeadByte(*pbTarget);
  80. BOOL fCompare = TRUE;
  81. if (!fTargetDBCS)
  82. {
  83. if (ulCharType & (CK_ALPHABET | CK_NUMERIC))
  84. {
  85. if (!IsCharAlphaNumeric(*pbTarget))
  86. fCompare = FALSE;
  87. }
  88. else
  89. {
  90. if (IsCharAlphaNumeric(*pbTarget))
  91. fCompare = FALSE;
  92. }
  93. }
  94. if (fCompare && CompareStringA(lcid,
  95. ((ulFuzzyLevel & FL_IGNORECASE) ? NORM_IGNORECASE | NORM_IGNOREKANATYPE | NORM_IGNOREWIDTH : 0) |
  96. ((ulFuzzyLevel & FL_LOOSE) ? NORM_IGNORECASE | NORM_IGNOREKANATYPE | NORM_IGNOREWIDTH : 0) |
  97. ((ulFuzzyLevel & FL_IGNORENONSPACE) ? NORM_IGNORENONSPACE : 0),
  98. pbPattern,
  99. cbPattern,
  100. pbTarget,
  101. ulcbStrCount(pbTarget, ulchPattern, langID)) == 2 )
  102. {
  103. fResult = TRUE;
  104. goto end;
  105. }
  106. // pszTarget may contain the hi-ansi characters. fTargetDBCS may
  107. // not be true.
  108. if (fTargetDBCS && ulcbTarget > 1)
  109. {
  110. ulcbTarget -= 2;
  111. pbTarget += 2;
  112. }
  113. else
  114. {
  115. ulcbTarget --;
  116. pbTarget ++;
  117. }
  118. }
  119. #else
  120. UINT i;
  121. ULONG ulBaseToPowerMod = 1;
  122. ULONG ulHashPattern = 0;
  123. ULONG ulHashTarget = 0;
  124. LCID lcid = GetUserDefaultLCID();
  125. LPBYTE pbTarget;
  126. LPBYTE pbPattern;
  127. LPBYTE pbTargetMax;
  128. LPBYTE pbPatternMax;
  129. BOOL fResult = FALSE;
  130. CHAR *rgchHash;
  131. // Validate parameters
  132. switch (ulFuzzyLevel & (FL_IGNORECASE | FL_IGNORENONSPACE))
  133. {
  134. default: case 0:
  135. rgchHash = (CHAR*)rgchCsds;
  136. break;
  137. case FL_IGNORECASE:
  138. rgchHash = (CHAR*)rgchCids;
  139. break;
  140. case FL_IGNORENONSPACE:
  141. rgchHash = (CHAR*)rgchCsdi;
  142. break;
  143. case FL_IGNORECASE | FL_IGNORENONSPACE:
  144. rgchHash = (CHAR*)rgchCidi;
  145. break;
  146. }
  147. // Special case for single character pattern strings
  148. if (cbPattern == 1 && cbTarget >= 1) {
  149. BYTE chPattern = (BYTE)*pszPattern;
  150. pbTarget = (LPBYTE)pszTarget;
  151. while (*pbTarget && *pbTarget != chPattern) {
  152. pbTarget++;
  153. }
  154. if (*pbTarget == chPattern) {
  155. return(pbTarget);
  156. } else {
  157. return(NULL); // not found
  158. }
  159. }
  160. //$ Is this what we want FL_LOOSE to mean?
  161. if (ulFuzzyLevel & FL_LOOSE)
  162. rgchHash = (CHAR*)rgchCids;
  163. pbTarget = (LPBYTE) pszTarget;
  164. pbPattern = (LPBYTE) pszPattern;
  165. pbTargetMax = pbTarget + cbTarget;
  166. pbPatternMax = pbPattern + cbPattern;
  167. if (cbPattern > cbTarget)
  168. goto end;
  169. // Compute the power of the left most character in base ulBase
  170. for (i = 1; i < cbPattern; i++)
  171. ulBaseToPowerMod = (ulBase * ulBaseToPowerMod) % ulPrime;
  172. // Calculate the hash function for the src (and the first dst)
  173. while (pbPattern < pbPatternMax)
  174. {
  175. ulHashPattern = (ulHashPattern*ulBase+rgchHash[*pbPattern]) % ulPrime;
  176. ulHashTarget = (ulHashTarget*ulBase+rgchHash[*pbTarget]) % ulPrime;
  177. pbPattern++;
  178. pbTarget++;
  179. }
  180. // Dynamically produce hash values for the string as we go
  181. for ( ;; )
  182. {
  183. if (ulHashPattern == ulHashTarget)
  184. {
  185. if (CompareStringA(lcid,
  186. ((ulFuzzyLevel & FL_IGNORECASE) ? NORM_IGNORECASE : 0) |
  187. ((ulFuzzyLevel & FL_LOOSE) ? NORM_IGNORECASE : 0) |
  188. ((ulFuzzyLevel & FL_IGNORENONSPACE) ? NORM_IGNORENONSPACE : 0),
  189. pbPattern-cbPattern, (UINT)cbPattern,
  190. pbTarget-cbPattern, (UINT)cbPattern) == 2)
  191. {
  192. fResult = TRUE;
  193. pbTarget -= cbPattern;
  194. goto end;
  195. }
  196. }
  197. #ifdef DEBUG
  198. if (ulHashPattern == ulHashTarget)
  199. DebugTrace( TEXT("This is very unprobable, unless you are doing ")
  200. TEXT("FL_EXACT and an case insensitive match came up ")
  201. TEXT("(or you are on DBCS)\n"));
  202. #endif
  203. if (pbTarget == pbTargetMax)
  204. goto end;
  205. ulHashTarget = (ulHashTarget+ulBase*ulPrime-
  206. rgchHash[*(pbTarget-cbPattern)]*ulBaseToPowerMod) % ulPrime;
  207. ulHashTarget = (ulHashTarget*ulBase+rgchHash[*pbTarget]) % ulPrime;
  208. pbTarget++;
  209. }
  210. #endif
  211. end:
  212. return fResult ? pbTarget : NULL;
  213. }
  214. BOOL FRKFindSubpsz(LPSTR pszTarget, ULONG cbTarget, LPSTR pszPattern,
  215. ULONG cbPattern, ULONG ulFuzzyLevel)
  216. {
  217. return !!LpszRKFindSubpsz (pszTarget,
  218. cbTarget,
  219. pszPattern,
  220. cbPattern,
  221. ulFuzzyLevel);
  222. }