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.

191 lines
5.1 KiB

  1. /*-----------------------------------------------------------------------------
  2. Program Specification
  3. in: search space s, pattern p
  4. out: a pointer where p is exactly matched at s[i], NULL indicates fail
  5. why: Boyer-Moore algorithm is best for general text search. On
  6. "average" it takes length(s)/length(p) steps to match p in s.
  7. ref: I recommend the following references:
  8. "Algorithms". Robert Sedgewick. Addison Wesley Publishing Company.
  9. 1988. 2nd addition. p286. QA76.6.S435 1983
  10. "Faster String Searches". Doctor Dobb's Journal. Volume 14
  11. Issue 7 July 1989. Costas Menico. p74.
  12. usage: e.g. to find a pattern "tiger" in a text in RAM starting at
  13. pointer "txtp" with a length of 1,000,000 characters,
  14. program like this:
  15. LPSTR matchp;
  16. SetFindPattern( "tiger" );
  17. matchp = Find( txtp, 1000000L );
  18. if (matchp != NULL)
  19. // found
  20. else
  21. // not found
  22. matchp = FindBackward( txtp + 1000000L - 1, 1000000L);
  23. if (matchp != NULL)
  24. // found
  25. else
  26. // not found
  27. Q: Can I use Find() with a GlobalLock() pointer in Windows?
  28. A: Yes.
  29. Q: Must I delcare my pointer as HPSTR (huge pointer) ?
  30. A: Not necessary. Find() and FindBackward() will convert your
  31. LPSTR as HPSTR. However, in your own code you must aware
  32. that you are holding a LPSTR and take care of the pointer
  33. arithmetic and conversion. (see demo.c for example)
  34. Q: What is the limit of the memory space I can search?
  35. A: To the limit of huge pointer implementation and your hardware.
  36. -----------------------------------------------------------------------------*/
  37. #include "pch.hpp"
  38. /*-----------------------------------------------------------------------------
  39. func: SetFindPattern
  40. desc: initialize the pattern to be matched and generate skip table
  41. pass: lpszPattern = pattern string
  42. rtrn: HFIND - the find handle for further text search
  43. -----------------------------------------------------------------------------*/
  44. HFIND SetFindPattern( LPTSTR lpszPattern )
  45. {
  46. register unsigned int j;
  47. register TCHAR c;
  48. HFIND hfind;
  49. hfind = (HFIND)MyAlloc(sizeof(FINDSTRUCT));
  50. hfind->plen = lstrlen( lpszPattern );
  51. if (hfind->plen > MAXPAT)
  52. hfind->plen = MAXPAT;
  53. #ifdef UNICODE
  54. wcstombs( (LPSTR)(hfind->p), lpszPattern, hfind->plen + 1 );
  55. #else
  56. lstrcpy( (LPSTR)(hfind->p), lpszPattern );
  57. #endif
  58. for (j=0; j<256; j++)
  59. {
  60. hfind->skip[j] = hfind->plen;
  61. }
  62. for (j=0; j<hfind->plen; j++)
  63. {
  64. c = lpszPattern[j];
  65. hfind->skip[c] = hfind->plen - (j +1);
  66. }
  67. return (hfind);
  68. }
  69. /*-----------------------------------------------------------------------------
  70. func: FreeFindPattern
  71. desc: free the memory occupied by SetFindPattern
  72. pass: hfind - the find handle
  73. rtrn: nothing
  74. -----------------------------------------------------------------------------*/
  75. void FreeFindPattern( HFIND hfind )
  76. {
  77. MyFree((LPTSTR)hfind);
  78. }
  79. /*-----------------------------------------------------------------------------
  80. func: Find
  81. desc: match a pattern defined in SetFindPattern against string s
  82. pass: hfind = the find handle created by SetFindPattern
  83. s = start of search space, slen = length of s
  84. rtrn: NULL = match fail
  85. else = a LPTSTR to p[0] in s matches p
  86. -----------------------------------------------------------------------------*/
  87. LPSTR Find( HFIND hfind, LPSTR s, long slen )
  88. {
  89. register int i;
  90. unsigned int n, j;
  91. register unsigned char c;
  92. LPSTR lpresult;
  93. i = hfind->plen;
  94. j = hfind->plen;
  95. do
  96. {
  97. c = *(s + (i - 1));
  98. if (c == hfind->p[j - 1])
  99. {
  100. i--;
  101. j--;
  102. }
  103. else
  104. {
  105. n = hfind->plen - j + 1;
  106. if (n > hfind->skip[c] )
  107. {
  108. i += n;
  109. }
  110. else
  111. {
  112. i += hfind->skip[c];
  113. }
  114. j = hfind->plen;
  115. }
  116. }
  117. while ((j >= 1) && (i <= slen));
  118. /* match fails */
  119. if (i >= slen)
  120. {
  121. lpresult = (LPSTR)NULL;
  122. }
  123. /* match successful */
  124. else
  125. {
  126. lpresult = s + i;
  127. }
  128. return (lpresult);
  129. }
  130. #ifdef TEST_MAIN
  131. #pragma message("Building with TEST_MAIN")
  132. #include <stdio.h>
  133. TCHAR test_buffer[]=TEXT("___________12191919191919This is string for testing our find ___________12191919191919function 12abE Is it in here somehwere ?");
  134. TCHAR test_pattern[]=TEXT("___________12191919191919");
  135. void main(void)
  136. {
  137. HFIND hFind;
  138. TCHAR *tmp;
  139. hFind=SetFindPattern(test_pattern);
  140. tmp=Find(hFind, test_buffer,strlen(test_buffer));
  141. if (tmp!=NULL) printf("Found pattern at offset %u, %s",tmp-test_buffer,tmp);
  142. FreeFindPattern(hFind);
  143. }
  144. #endif