This is my patch patch.0a for perl5.000.
[p5sagit/p5-mst-13.2.git] / lib / Search / Dict.pm
1 package Search::Dict;
2 require 5.000;
3 require Exporter;
4
5 @ISA = qw(Exporter);
6 @EXPORT = qw(look);
7
8 # Usage: look(*FILEHANDLE,$key,$dict,$fold)
9
10 # Sets file position in FILEHANDLE to be first line greater than or equal
11 # (stringwise) to $key.  Pass flags for dictionary order and case folding.
12
13 sub look {
14     local(*FH,$key,$dict,$fold) = @_;
15     local($max,$min,$mid,$_);
16     local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
17        $blksize,$blocks) = stat(FH);
18     $blksize = 8192 unless $blksize;
19     $key =~ s/[^\w\s]//g if $dict;
20     $key =~ tr/A-Z/a-z/ if $fold;
21     $max = int($size / $blksize);
22     while ($max - $min > 1) {
23         $mid = int(($max + $min) / 2);
24         seek(FH,$mid * $blksize,0);
25         $_ = <FH> if $mid;              # probably a partial line
26         $_ = <FH>;
27         chop;
28         s/[^\w\s]//g if $dict;
29         tr/A-Z/a-z/ if $fold;
30         if ($_ lt $key) {
31             $min = $mid;
32         }
33         else {
34             $max = $mid;
35         }
36     }
37     $min *= $blksize;
38     seek(FH,$min,0);
39     <FH> if $min;
40     while (<FH>) {
41         chop;
42         s/[^\w\s]//g if $dict;
43         y/A-Z/a-z/ if $fold;
44         last if $_ ge $key;
45         $min = tell(FH);
46     }
47     seek(FH,$min,0);
48     $min;
49 }
50
51 1;
52