home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / PNL Libraries / MyFastFind.p < prev    next >
Encoding:
Text File  |  1997-04-09  |  3.6 KB  |  155 lines  |  [TEXT/CWIE]

  1. unit MyFastFind;
  2.  
  3. interface
  4.  
  5.     uses
  6.         Types;
  7.  
  8.     function SetFastFindSize (p: Ptr; siz: longint): OSErr;
  9.     function SetFastFindWord (p: Ptr; theWord: Str63): OSErr;
  10.     function SetFastFindFile (p: Ptr; refnum: integer): OSErr;
  11.     function StartFastFind (p: Ptr): OSErr;
  12.     function FastFind (p: Ptr): longint;
  13.     function OldFastFind (p: Ptr): longint;
  14.  
  15. implementation
  16.  
  17.     uses
  18.         Errors, Files;
  19.     type
  20.         dataArray = packed array[1..1000000] of char;
  21.         wordType = Str63;
  22.         findRecord = record
  23.                 size: longint;
  24.                 datap: ^dataArray;
  25.                 word: wordType;
  26.                 rn: integer;
  27.                 filelen, pos, count, data_index: longint;
  28.                 skip: packed array[char] of Byte;
  29.                 data: integer;
  30.             end;
  31.         findPtr = ^findRecord;
  32.  
  33.     function UpCaseChar (ch: char): char;
  34.     inline
  35.         $301F, $0C00, $0061, $6500, $000E, $0C00, $007B, $6400, $0006, $0400, $0020, $3E80;
  36.  
  37.     function SetFastFindSize (p: Ptr; siz: longint): OSErr;
  38.     begin
  39.         with findPtr(p)^ do begin
  40.             size := siz - SizeOf(findRecord);
  41.             datap := @data;
  42.             if size > 256 then
  43.                 SetFastFindSize := noErr
  44.             else
  45.                 SetFastFindSize := paramErr;
  46.         end;
  47.     end;
  48.  
  49.     function SetFastFindWord (p: Ptr; theWord: Str63): OSErr;
  50.         var
  51.             i: integer;
  52.     begin
  53.         with findPtr(p)^ do begin
  54.             word := theWord;
  55.             for i := 0 to 255 do
  56.                 skip[chr(i)] := length(word);
  57.             for i := 1 to length(word) do begin
  58.                 word[i] := UpCaseChar(word[i]);
  59.                 skip[word[i]] := length(word) - i;
  60.             end;
  61.         end;
  62.         SetFastFindWord := noErr;
  63.     end;
  64.  
  65.     function SetFastFindFile (p: Ptr; refnum: integer): OSErr;
  66.         var
  67.             oe: OSErr;
  68.     begin
  69.         with findPtr(p)^ do begin
  70.             rn := refnum;
  71.             oe := GetEOF(rn, filelen);
  72.             if oe = noErr then
  73.                 oe := GetFPos(rn, pos);
  74.             if oe = noErr then begin
  75.                 count := size;
  76.                 oe := FSRead(rn, count, Ptr(datap));
  77.                 if (oe = eofErr) and (count > 0) then
  78.                     oe := noErr;
  79.             end;
  80.         end;
  81.         SetFastFindFile := oe;
  82.     end;
  83.  
  84.     function StartFastFind (p: Ptr): OSErr;
  85.     begin
  86.         with findPtr(p)^ do begin
  87.             data_index := length(word);
  88.             if data_index > count then
  89.                 StartFastFind := -1
  90.             else
  91.                 StartFastFind := noErr;
  92.         end;
  93.     end;
  94.  
  95.     function OldFastFind (p: Ptr): longint;
  96.         var
  97.             oe: OSErr;
  98.             ch: char;
  99.             amount: 0..63;
  100.             wi: integer;
  101.     begin
  102.         with findPtr(p)^ do begin
  103.             oe := noErr;
  104.             wi := length(word);
  105.             while (oe = noErr) and (wi <> 0) and (pos + data_index < filelen) do begin
  106. { data_index is the last character in data that we are checking now }
  107.  
  108.                 if data_index > count then begin
  109.                     amount := count - (data_index - length(word));
  110.                     pos := pos + count - amount;
  111.                     BlockMove(@datap^[data_index - length(word) + 1], Ptr(datap), amount);
  112.                     data_index := length(word);
  113.                     count := size - amount;
  114.                     oe := FSRead(rn, count, @datap^[amount + 1]);
  115.                     if oe = eofErr then
  116.                         oe := noErr;
  117.                     count := count + amount;
  118.                 end;
  119.                 if (data_index > count) and (oe = noErr) then
  120.                     oe := -1;
  121.                 if oe = noErr then begin
  122.                     repeat
  123.                         ch := UpCaseChar(datap^[data_index]);
  124.                         if ch = word[wi] then begin
  125.                             data_index := data_index - 1;
  126.                             wi := wi - 1;
  127.                             if wi = 0 then
  128.                                 leave;
  129.                         end
  130.                         else begin
  131. {    data_index := data_index + Max(length(word) - wi + 1, skip[ch]);}
  132.                             if length(word) - wi + 1 > skip[ch] then
  133.                                 data_index := data_index + length(word) - wi + 1
  134.                             else
  135.                                 data_index := data_index + skip[ch];
  136.                             wi := length(word);
  137.                             if data_index > count then
  138.                                 leave;
  139.                         end;
  140.                     until false;
  141.                 end;
  142.             end;
  143.             if wi <> 0 then begin
  144.                 if oe >= 0 then
  145.                     oe := -1;
  146.                 OldFastFind := oe;
  147.             end
  148.             else begin
  149.                 OldFastFind := pos + data_index;
  150.                 data_index := data_index + length(word) + 1;
  151.             end;
  152.         end;
  153.     end;
  154.  
  155. end.