source: branches/delphi/StringTables.pas

Last change on this file was 6, checked in by chronos, 7 years ago
  • Modified: Formated all project source files using Delphi formatter as original indentation and other formatting was really bad.
File size: 4.6 KB
Line 
1{$INCLUDE switches}
2unit StringTables;
3
4interface
5
6const
7 MaxCount = 4000;
8
9type
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;
25
26implementation
27
28uses
29 Classes, SysUtils;
30
31constructor TStringTable.Create;
32begin
33 Data := nil;
34end;
35
36destructor TStringTable.Destroy;
37begin
38 if Data <> nil then
39 FreeMem(Data);
40end;
41
42function TStringTable.LoadFromFile(const FileName: string): boolean;
43var
44 nData, i: integer;
45 f: TFileStream;
46begin
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 end;
71end;
72
73function TStringTable.GetHandle(const Item: AnsiString): integer;
74var
75 i, l: integer;
76begin
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
83end;
84
85function TStringTable.LookupByHandle(Handle: integer; Index: integer): string;
86var
87 s: string;
88begin
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
102 begin
103 inc(Handle);
104 if (Lines[Handle][0] <> #0) and (Lines[Handle][0] <> '''') then
105 begin
106 if (s <> '') and (s[Length(s)] <> '\') then
107 s := s + ' ';
108 s := s + Lines[Handle];
109 end
110 end;
111 result := s
112 end
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 := '*';
127end;
128
129function TStringTable.Lookup(const Item: string; Index: integer): string;
130var
131 Handle: integer;
132begin
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])
143end;
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
155 result:=Fallback.Lookup(Item, Index);
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
167function TStringTable.Search(const Content: string;
168 var Handle, Index: integer): boolean;
169var
170 h, i: integer;
171 UContent: string;
172begin
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;
200end;
201
202end.
Note: See TracBrowser for help on using the repository browser.