Changeset 6 for trunk/StringTables.pas
- Timestamp:
- Jan 7, 2017, 11:32:14 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/StringTables.pas
r5 r6 1 1 {$INCLUDE switches} 2 3 2 unit StringTables; 4 3 … … 6 5 7 6 const 8 MaxCount=4000;7 MaxCount = 4000; 9 8 10 9 type 11 TCharList=array[0..9999999] of AnsiChar; 12 13 TStringTable=class 14 constructor Create; 15 destructor Destroy; override; 16 function LoadFromFile(const FileName: String): boolean; 17 function GetHandle(const Item: AnsiString): integer; 18 function LookupByHandle(Handle: integer; Index: integer =-1): string; 19 function Lookup(const Item: string; Index: integer =-1): string; 20 function Search(const Content: string; var Handle, Index: integer): boolean; 21 protected 22 Count: integer; 23 Data: ^TCharList; 24 Lines: array[0..MaxCount-1] of PAnsiChar; 25 end; 26 10 TCharList = array [0 .. 9999999] of AnsiChar; 11 12 TStringTable = class 13 constructor Create; 14 destructor Destroy; override; 15 function LoadFromFile(const FileName: String): boolean; 16 function GetHandle(const Item: AnsiString): integer; 17 function LookupByHandle(Handle: integer; Index: integer = -1): string; 18 function Lookup(const Item: string; Index: integer = -1): string; 19 function Search(const Content: string; var Handle, Index: integer): boolean; 20 protected 21 Count: integer; 22 Data: ^TCharList; 23 Lines: array [0 .. MaxCount - 1] of PAnsiChar; 24 end; 27 25 28 26 implementation 29 27 30 28 uses 31 Classes,SysUtils; 32 29 Classes, SysUtils; 33 30 34 31 constructor TStringTable.Create; 35 32 begin 36 Data:=nil;33 Data := nil; 37 34 end; 38 35 39 36 destructor TStringTable.Destroy; 40 37 begin 41 if Data<>nil then FreeMem(Data); 42 end; 43 44 function TStringTable.LoadFromFile(const FileName:string): boolean; 45 var 46 nData, i: integer; 47 f: TFileStream; 48 begin 49 if Data<>nil then FreeMem(Data); 50 try 51 f:=TFileStream.Create(FileName, fmOpenRead or fmShareExclusive); 52 except 53 result:=false; 54 exit; 55 end; 56 result:=true; 57 nData:=f.Size; 58 GetMem(Data,nData+1); 59 f.read(Data^,nData); 60 f.Free; 61 i:=0; 62 Count:=0; 63 while (i<nData) and (Count<MaxCount) do 64 begin 65 Lines[Count]:=@Data[i]; 66 while (i<nData) and (Data[i]<>#13) do inc(i); 67 Data[i]:=#0; 68 inc(i,2); 69 inc(Count); 38 if Data <> nil then 39 FreeMem(Data); 40 end; 41 42 function TStringTable.LoadFromFile(const FileName: string): boolean; 43 var 44 nData, i: integer; 45 f: TFileStream; 46 begin 47 if Data <> nil then 48 FreeMem(Data); 49 try 50 f := TFileStream.Create(FileName, fmOpenRead or fmShareExclusive); 51 except 52 result := false; 53 exit; 54 end; 55 result := true; 56 nData := f.Size; 57 GetMem(Data, nData + 1); 58 f.read(Data^, nData); 59 f.Free; 60 i := 0; 61 Count := 0; 62 while (i < nData) and (Count < MaxCount) do 63 begin 64 Lines[Count] := @Data[i]; 65 while (i < nData) and (Data[i] <> #13) do 66 inc(i); 67 Data[i] := #0; 68 inc(i, 2); 69 inc(Count); 70 70 end; 71 71 end; … … 73 73 function TStringTable.GetHandle(const Item: AnsiString): integer; 74 74 var 75 i,l: integer; 76 begin 77 l:=Length(Item); 78 i:=Count-1; 79 while (i>=0) and ((Lines[i][0]<>'#') 80 or (StrLComp(Lines[i]+1,@Item[1],l)<>0) 81 or (Lines[i][l+1]<>#0) and (Lines[i][l+1]<>' ')) do 82 dec(i); 83 result:=i 84 end; 85 86 function TStringTable.LookupByHandle(Handle: Integer; Index: integer): string; 87 var 88 s: string; 89 begin 90 if Index<0 then 91 if Handle<0 then begin result:=''; exit end 92 else 93 begin 94 if pos(' ',Lines[Handle])=0 then s:='' 95 else s:=copy(Lines[Handle],pos(' ',Lines[Handle])+1,MaxInt); 96 while (Handle+1<Count) and (Lines[Handle+1][0]<>'#') do 75 i, l: integer; 76 begin 77 l := Length(Item); 78 i := Count - 1; 79 while (i >= 0) and ((Lines[i][0] <> '#') or (StrLComp(Lines[i] + 1, @Item[1], 80 l) <> 0) or (Lines[i][l + 1] <> #0) and (Lines[i][l + 1] <> ' ')) do 81 dec(i); 82 result := i 83 end; 84 85 function TStringTable.LookupByHandle(Handle: integer; Index: integer): string; 86 var 87 s: string; 88 begin 89 if Index < 0 then 90 if Handle < 0 then 91 begin 92 result := ''; 93 exit 94 end 95 else 96 begin 97 if pos(' ', Lines[Handle]) = 0 then 98 s := '' 99 else 100 s := copy(Lines[Handle], pos(' ', Lines[Handle]) + 1, MaxInt); 101 while (Handle + 1 < Count) and (Lines[Handle + 1][0] <> '#') do 97 102 begin 98 inc(Handle);99 if (Lines[Handle][0]<>#0) and (Lines[Handle][0]<>'''') then103 inc(Handle); 104 if (Lines[Handle][0] <> #0) and (Lines[Handle][0] <> '''') then 100 105 begin 101 if (s<>'') and (s[Length(s)]<>'\') then s:=s+' '; 102 s:=s+Lines[Handle]; 106 if (s <> '') and (s[Length(s)] <> '\') then 107 s := s + ' '; 108 s := s + Lines[Handle]; 103 109 end 104 110 end; 105 result:=s111 result := s 106 112 end 107 else if Handle+Index+1>=Count then begin result:=''; exit end 108 else result:=Lines[Handle+Index+1]; 109 while (result<>'') and ((result[1]=' ') or (result[1]=#9)) do 110 Delete(result,1,1); 111 while (result<>'') 112 and ((result[Length(result)]=' ') or (result[Length(result)]=#9)) do 113 Delete(result,Length(result),1); 114 if result='' then result:='*'; 113 else if Handle + Index + 1 >= Count then 114 begin 115 result := ''; 116 exit 117 end 118 else 119 result := Lines[Handle + Index + 1]; 120 while (result <> '') and ((result[1] = ' ') or (result[1] = #9)) do 121 Delete(result, 1, 1); 122 while (result <> '') and ((result[Length(result)] = ' ') or 123 (result[Length(result)] = #9)) do 124 Delete(result, Length(result), 1); 125 if result = '' then 126 result := '*'; 115 127 end; 116 128 117 129 function TStringTable.Lookup(const Item: string; Index: integer): string; 118 130 var 119 Handle: integer; 120 begin 121 Handle:=Gethandle(Item); 122 if Handle>=0 then result:=LookupByHandle(Handle, Index) 123 else result:=''; 124 if result='' then 125 if Index<0 then result:=Format('[%s]',[Item]) 126 else result:=Format('[%s %d]',[Item,Index]) 127 end; 128 129 {might become necessary for 1.3 130 131 function TStringTable.Lookup(const Fallback: TStringTable; const Item: string; Index: integer): string; 132 var 133 Handle: integer; 134 begin 135 Handle:=Gethandle(Item); 136 if Handle>=0 then result:=LookupByHandle(Handle, Index) 137 else result:=''; 138 if result='' then 131 Handle: integer; 132 begin 133 Handle := GetHandle(Item); 134 if Handle >= 0 then 135 result := LookupByHandle(Handle, Index) 136 else 137 result := ''; 138 if result = '' then 139 if Index < 0 then 140 result := Format('[%s]', [Item]) 141 else 142 result := Format('[%s %d]', [Item, Index]) 143 end; 144 145 { might become necessary for 1.3 146 147 function TStringTable.Lookup(const Fallback: TStringTable; const Item: string; Index: integer): string; 148 var 149 Handle: integer; 150 begin 151 Handle:=Gethandle(Item); 152 if Handle>=0 then result:=LookupByHandle(Handle, Index) 153 else result:=''; 154 if result='' then 139 155 result:=Fallback.Lookup(Item, Index); 140 end; 141 142 function TStringTable.TryLookup(const Item: string; Index: integer): string; 143 var 144 Handle: integer; 145 begin 146 Handle:=Gethandle(Item); 147 if Handle>=0 then result:=LookupByHandle(Handle, Index) 148 else result:=''; 149 end;} 150 151 function TStringTable.Search(const Content: string; var Handle, Index: integer): boolean; 152 var 153 h,i: integer; 154 UContent: string; 155 begin 156 UContent:=UpperCase(Content); 157 h:=Handle; 158 if h<0 then i:=0 159 else i:=Index+1; 160 repeat 161 if h+i+1>=Count then 162 begin result:=false; exit end; 163 if Lines[h+i+1][0]='#' then 164 begin h:=h+i+1; i:=-1 end; 165 if (h>=0) and not (Lines[h+i+1][0] in ['#',':',';']) 166 and (pos(UContent, UpperCase(Lines[h+i+1]))>0) then 167 begin Index:=i; Handle:=h; result:=true; exit end; 168 inc(i); 169 until false; 156 end; 157 158 function TStringTable.TryLookup(const Item: string; Index: integer): string; 159 var 160 Handle: integer; 161 begin 162 Handle:=Gethandle(Item); 163 if Handle>=0 then result:=LookupByHandle(Handle, Index) 164 else result:=''; 165 end; } 166 167 function TStringTable.Search(const Content: string; 168 var Handle, Index: integer): boolean; 169 var 170 h, i: integer; 171 UContent: string; 172 begin 173 UContent := UpperCase(Content); 174 h := Handle; 175 if h < 0 then 176 i := 0 177 else 178 i := Index + 1; 179 repeat 180 if h + i + 1 >= Count then 181 begin 182 result := false; 183 exit 184 end; 185 if Lines[h + i + 1][0] = '#' then 186 begin 187 h := h + i + 1; 188 i := -1 189 end; 190 if (h >= 0) and not(Lines[h + i + 1][0] in ['#', ':', ';']) and 191 (pos(UContent, UpperCase(Lines[h + i + 1])) > 0) then 192 begin 193 Index := i; 194 Handle := h; 195 result := true; 196 exit 197 end; 198 inc(i); 199 until false; 170 200 end; 171 201 172 202 end. 173
Note:
See TracChangeset
for help on using the changeset viewer.