• R/O
  • SSH
  • HTTPS

dzlargetextview: Commit


Commit MetaInfo

Revision263 (tree)
Zeit2016-05-30 00:51:05
Autortwm

Log Message

* No longer uses a TInt64List but a Tint64ListFile which is stored in a file. Can now fully index and display the 48 gig dump of Wikipedia containing roughly 790 million lines.
* updated manifest for Windows 10

Ändern Zusammenfassung

Diff

--- trunk/src/dzLargeTextViewer.dpr (revision 262)
+++ trunk/src/dzLargeTextViewer.dpr (revision 263)
@@ -7,14 +7,19 @@
77 u_Int64List in 'u_Int64List.pas',
88 w_GotoLine in 'w_GotoLine.pas' {f_GotoLine},
99 w_Search in 'w_Search.pas' {f_Search},
10- JclUnicode in '..\libs\jcl\source\common\JclUnicode.pas';
10+ JclUnicode in '..\libs\jcl\source\common\JclUnicode.pas',
11+ u_LargeTextAccess in 'u_LargeTextAccess.pas',
12+ u_Int64ListFile in 'u_Int64ListFile.pas';
1113
1214 {$R *_version.res}
1315 {$R *_icon.res}
1416
17+var
18+ f_Search: Tf_Search;
1519 begin
1620 Application.Initialize;
1721 Application.MainFormOnTaskbar := True;
22+// Application.CreateForm(Tf_Search, f_Search);
1823 Application.CreateForm(Tf_LargeTextViewer, f_LargeTextViewer);
1924 Application.Run;
2025 end.
--- trunk/src/dzLargeTextViewer.dproj (revision 262)
+++ trunk/src/dzLargeTextViewer.dproj (revision 263)
@@ -103,6 +103,278 @@
103103
104104
105105
106+
107+
108+
109+
110+
111+
112+
113+
114+
115+
116+
117+
118+
119+
120+
121+
122+
123+
124+
125+
126+
127+
128+
129+
130+
131+
132+
133+
134+
135+
136+
137+
138+
139+
140+
141+
142+
143+
144+
145+
146+
147+
148+
149+
150+
151+
152+
153+
154+
155+
156+
157+
158+
159+
160+
161+
162+
163+
164+
165+
166+
167+
168+
169+
170+
171+
172+
173+
174+
175+
176+
177+
178+
179+
180+
181+
182+
183+
184+
185+
186+
187+
188+
189+
190+
191+
192+
193+
194+
195+
196+
197+
198+
199+
200+
201+
202+
203+
204+
205+
206+
207+
208+
209+
210+
211+
212+
213+
214+
215+
216+
217+
218+
219+
220+
221+
222+
223+
224+
225+
226+
227+
228+
229+
230+
231+
232+
233+
234+
235+
236+
237+
238+
239+
240+
241+
242+
243+
244+
245+
246+
247+
248+
249+
250+
251+
252+
253+
254+
255+
256+
257+
258+
259+
260+
261+
262+
263+
264+
265+
266+
267+
268+
269+
270+
271+
272+
273+
274+
275+
276+
277+
278+
279+
280+
281+
282+
283+
284+
285+
286+
287+
288+
289+
290+
291+
292+
293+
294+
295+
296+
297+
298+
299+
300+
301+
302+
303+
304+
305+
306+
307+
308+
309+
310+
311+
312+
313+
314+
315+
316+
317+
318+
319+
320+
321+
322+
323+
324+
325+
326+
327+
328+
329+
330+
331+
332+
333+
334+
335+
336+
337+
338+
339+
340+
341+
342+
343+
344+
345+
346+
347+
348+
349+
350+
351+
352+
353+
354+
355+
356+
357+
358+
359+
360+
361+
362+
363+
364+
365+
366+
367+
368+
369+
370+
371+
372+
373+
374+
375+
376+
377+
106378 <Excluded_Packages Name="$(BDS)\bin\dcloffice2k100.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
107379 <Excluded_Packages Name="$(BDS)\bin\dclofficexp100.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
108380 <Excluded_Packages Name="$(BDS)\bin\bcbie100.bpl">File c:\program files (x86)\codegear\rad studio\5.0\bin\bcbie100.bpl not found</Excluded_Packages>
@@ -133,6 +405,8 @@
133405 </DelphiCompile>
134406 <DCCReference Include="..\libs\jcl\source\common\JclUnicode.pas" />
135407 <DCCReference Include="u_Int64List.pas" />
408+ <DCCReference Include="u_Int64ListFile.pas" />
409+ <DCCReference Include="u_LargeTextAccess.pas" />
136410 <DCCReference Include="u_TextFileIndexer.pas" />
137411 <DCCReference Include="w_GotoLine.pas">
138412 <Form>f_GotoLine</Form>
--- trunk/src/dzLargeTextViewer.manifest.in (revision 262)
+++ trunk/src/dzLargeTextViewer.manifest.in (revision 263)
@@ -33,6 +33,8 @@
3333 <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
3434 <!-- We support Windows 8.1 -->
3535 <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
36+ <!-- We support Windows 10 -->
37+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
3638 </application>
3739 </compatibility>
3840
--- trunk/src/dzLargeTextViewer_version.ini (revision 262)
+++ trunk/src/dzLargeTextViewer_version.ini (revision 263)
@@ -1,6 +1,6 @@
11 [Version Info]
22 AutoIncBuild=0
3-Build=97
3+Build=190
44 MajorVer=1
55 MinorVer=0
66 Release=0
@@ -7,7 +7,7 @@
77 Revision=0
88
99 [Version Info Keys]
10-FileVersion=1.0.0.97
10+FileVersion=1.0.0.190
1111 ProductVersion={today}
1212 FileDescription=Viewer for large text files
1313 OriginalFilename=dzLargeTextViewer.exe
--- trunk/src/u_Int64List.pas (revision 262)
+++ trunk/src/u_Int64List.pas (revision 263)
@@ -14,12 +14,13 @@
1414 FCapacity: integer;
1515 FCount: integer;
1616 procedure Grow;
17- procedure SetCapacity(_NewCapacity: Integer);
17+ procedure SetCapacity(_NewCapacity: integer);
1818 function GetItems(_Idx: integer): Int64;
1919 procedure SetItems(_Idx: integer; const Value: Int64);
2020 public
2121 function Add(_Value: Int64): integer;
2222 property Items[_Idx: integer]: Int64 read GetItems write SetItems;
23+ property Capacity: integer read FCapacity write SetCapacity;
2324 property Count: integer read FCount;
2425 end;
2526
@@ -41,7 +42,7 @@
4142
4243 procedure TInt64List.Grow;
4344 var
44- Delta: Integer;
45+ Delta: integer;
4546 begin
4647 if FCapacity > 64 then
4748 Delta := FCapacity div 4
@@ -52,7 +53,7 @@
5253 SetCapacity(FCapacity + Delta);
5354 end;
5455
55-procedure TInt64List.SetCapacity(_NewCapacity: Integer);
56+procedure TInt64List.SetCapacity(_NewCapacity: integer);
5657 begin
5758 if (_NewCapacity < FCount) or (_NewCapacity > MaxListSize) then
5859 raise Exception.CreateFmt(_('List capacity out of bounds (%d)'), [_NewCapacity]);
@@ -75,4 +76,3 @@
7576 end;
7677
7778 end.
78-
--- trunk/src/u_Int64ListFile.pas (nonexistent)
+++ trunk/src/u_Int64ListFile.pas (revision 263)
@@ -0,0 +1,96 @@
1+unit u_Int64ListFile;
2+
3+interface
4+
5+uses
6+ Windows,
7+ SysUtils,
8+ Classes,
9+ u_dzTranslator,
10+ u_dzFileStreams,
11+ u_dzFileUtils;
12+
13+type
14+ TInt64ListFile = class
15+ private
16+ FTempDir: IUniqueTempDir;
17+ FBuffer: array[0..1023] of Int64;
18+ FOffset: Int64;
19+ FCount: Int64;
20+ FTempFile: TdzFile;
21+ function GetItems(_Idx: Int64): Int64;
22+ procedure SetItems(_Idx: Int64; const Value: Int64);
23+ procedure AssureBufferFor(_Idx: integer);
24+ public
25+ constructor Create(_fn: string = '');
26+ destructor Destroy; override;
27+ function Add(_Value: Int64): Int64;
28+ property Items[_Idx: Int64]: Int64 read GetItems write SetItems;
29+ property Count: Int64 read FCount;
30+ end;
31+
32+implementation
33+
34+uses
35+ RTLConsts;
36+
37+{ TInt64ListFile }
38+
39+constructor TInt64ListFile.Create(_fn: string);
40+begin
41+ inherited Create;
42+ if _fn = '' then begin
43+ FTempDir := TFileSystem.CreateUniqueTempDir();
44+ _fn := FTempDir.PathBS + 'index.dat';
45+ end;
46+ FTempFile := TdzFile.Create(_fn);
47+ FTempFile.AccessMode := faReadWrite;
48+ FTempFile.ShareMode := fsNoSharing;
49+ FTempFile.CreateDisposition := fcCreateFailIfExists;
50+ FTempFile.Open;
51+ ZeroMemory(@FBuffer, SizeOf(FBuffer));
52+ FOffset := 0;
53+end;
54+
55+destructor TInt64ListFile.Destroy;
56+begin
57+ FreeAndNil(FTempFile);
58+ inherited;
59+end;
60+
61+function TInt64ListFile.Add(_Value: Int64): Int64;
62+begin
63+ Result := FCount;
64+ AssureBufferFor(Result);
65+ FBuffer[Result - FOffset] := _Value;
66+ Inc(FCount);
67+end;
68+
69+procedure TInt64ListFile.AssureBufferFor(_Idx: integer);
70+begin
71+ if (_Idx < FOffset) or (_Idx >= FOffset + Length(FBuffer)) then begin
72+ FTempFile.Position := FOffset * SizeOf(Int64);
73+ FTempFile.WriteBuffer(FBuffer, SizeOf(FBuffer));
74+ FOffset := (_Idx div Length(FBuffer)) * Length(FBuffer);
75+ if FOffset * SizeOf(Int64) < FTempFile.Size then begin
76+ FTempFile.Position := FOffset * SizeOf(Int64);
77+ FTempFile.ReadBuffer(FBuffer, SizeOf(FBuffer));
78+ end else
79+ ZeroMemory(@FBuffer, SizeOf(FBuffer));
80+ end;
81+end;
82+
83+function TInt64ListFile.GetItems(_Idx: Int64): Int64;
84+begin
85+ if (_Idx < 0) or (_Idx >= FCount) then
86+ raise Exception.CreateFmt(_('List index out of bounds (%d)'), [_Idx]);
87+ AssureBufferFor(_Idx);
88+ Result := FBuffer[_Idx - FOffset];
89+end;
90+
91+procedure TInt64ListFile.SetItems(_Idx: Int64; const Value: Int64);
92+begin
93+
94+end;
95+
96+end.
--- trunk/src/u_LargeTextAccess.pas (nonexistent)
+++ trunk/src/u_LargeTextAccess.pas (revision 263)
@@ -0,0 +1,82 @@
1+unit u_LargeTextAccess;
2+
3+interface
4+
5+uses
6+ SysUtils,
7+ Classes,
8+ u_dzFileStreams;
9+
10+type
11+ TLargeTextAccess = class
12+ public
13+ type
14+ TOptimizeForEnum = (ofForward, ofBackward, ofBoth);
15+ private
16+ const
17+ BUFFER_SIZE = 1024 * 128;
18+ var
19+ FOptimizeFor: TOptimizeForEnum;
20+ FFilename: string;
21+ FStream: TdzFile;
22+ FLength: Int64;
23+ FOffset: Int64;
24+ FBuffer: array[0..BUFFER_SIZE - 1] of char;
25+ public
26+ constructor Create(const _fn: string; _OptimizeFor: TOptimizeForEnum = ofBoth);
27+ destructor Destroy; override;
28+ function GetChar(_Idx: Int64): char;
29+ function GetLength: Int64;
30+ end;
31+
32+implementation
33+
34+{ TLargeTextAccess }
35+
36+constructor TLargeTextAccess.Create(const _fn: string; _OptimizeFor: TOptimizeForEnum = ofBoth);
37+begin
38+ inherited Create;
39+ FFilename := _fn;
40+ FOptimizeFor := _OptimizeFor;
41+ FStream := TdzFile.Create(FFilename);
42+ FStream.OpenReadonly;
43+ FLength := FStream.Size;
44+ FOffset := -BUFFER_SIZE;
45+end;
46+
47+destructor TLargeTextAccess.Destroy;
48+begin
49+ FreeAndNil(FStream);
50+ inherited;
51+end;
52+
53+function TLargeTextAccess.GetChar(_Idx: Int64): char;
54+begin
55+ if (_Idx < 0) or (_Idx >= FLength) then
56+ raise Exception.CreateFmt('Index %d out of range.', [_Idx]);
57+
58+ if (_Idx < FOffset) or (_Idx >= FOffset + BUFFER_SIZE) then begin
59+ case FOptimizeFor of
60+ ofForward:
61+ FOffset := _Idx;
62+ ofBackward:
63+ FOffset := _Idx - BUFFER_SIZE + 1;
64+ else // ofBoth
65+ FOffset := _Idx - BUFFER_SIZE div 2 + 1;
66+ end;
67+ if FOffset < 0 then
68+ FOffset := 0;
69+ if FOffset >= FLength then
70+ FOffset := FLength - 1;
71+ FStream.Position := FOffset;
72+ FStream.Read(FBuffer, BUFFER_SIZE);
73+ end;
74+ Result := FBuffer[_Idx - FOffset]
75+end;
76+
77+function TLargeTextAccess.GetLength: Int64;
78+begin
79+ Result := FLength;
80+end;
81+
82+end.
--- trunk/src/u_TextFileIndexer.pas (revision 262)
+++ trunk/src/u_TextFileIndexer.pas (revision 263)
@@ -6,16 +6,21 @@
66 SysUtils,
77 Classes,
88 u_Int64List,
9- u_dzCriticalSection;
9+ u_Int64ListFile,
10+ u_dzCriticalSection,
11+ u_LargeTextAccess;
1012
1113 type
1214 TTextFileIndexer = class
1315 private
16+ type
17+ TLineIndexes = TInt64ListFile;
18+ private
1419 FCritSect: TdzCriticalSection;
15- FLineIndexes: TInt64List;
20+ FLineIndexes: TLineIndexes;
1621 FIsDone: boolean;
1722 FFilename: string;
18- FAbortRequested: Boolean;
23+ FAbortRequested: boolean;
1924 function GetLineIndex(_Idx: integer): Int64;
2025 function GetLineIndexCount: integer;
2126 public
@@ -31,6 +36,7 @@
3136 implementation
3237
3338 uses
39+ u_dzConvertUtils,
3440 u_dzFileStreams;
3541
3642 { TTextFileIndexer }
@@ -38,7 +44,8 @@
3844 constructor TTextFileIndexer.Create(const _Filename: string);
3945 begin
4046 inherited Create;
41- FLineIndexes := TInt64List.Create;
47+ FLineIndexes := TLineIndexes.Create;
48+// FLineIndexes.Capacity := MaxListSize; // OneGibiByte div SizeOf(Int64);
4249 FFilename := _Filename;
4350 FCritSect := TdzCriticalSection.Create;
4451 end;
@@ -51,43 +58,37 @@
5158 end;
5259
5360 procedure TTextFileIndexer.Execute;
54-const
55- BUFFER_SIZE = 1024 * 128;
61+
62+ procedure AddIdx(_Idx: Int64);
63+ begin
64+ FCritSect.Enter;
65+ try
66+ FLineIndexes.Add(_Idx);
67+ finally
68+ FCritSect.Leave;
69+ end;
70+ end;
71+
5672 var
57- st: TdzFile;
58- buffer: array[0..BUFFER_SIZE - 1] of char;
59- Offset: Int64;
60- BytesRead: Integer;
61- i: Integer;
73+ i: Int64;
74+ lta: TLargeTextAccess;
6275 begin
6376 FAbortRequested := False;
6477 FIsDone := False;
65- st := TdzFile.Create(FFilename);
78+ lta := TLargeTextAccess.Create(FFilename, ofForward);
6679 try
67- st.OpenReadonly;
68- FCritSect.Enter;
69- try
70- FLineIndexes.Add(0);
71- finally
72- FCritSect.Leave;
73- end;
74- while not st.EOF do begin
75- Offset := st.Position;
76- BytesRead := st.Read(Buffer, SizeOf(Buffer));
77- for i := 0 to BytesRead - 1 do
78- if buffer[i] = #10 then begin
79- FCritSect.Enter;
80- try
81- FLineIndexes.Add(Offset + i + 1);
82- finally
83- FCritSect.Leave;
84- end;
85- end;
80+ AddIdx(0);
81+ i := 0;
82+ while i < lta.GetLength do begin
83+ if lta.GetChar(i) = #10 then begin
84+ AddIdx(i + 1);
85+ end;
86+ Inc(i);
8687 if FAbortRequested then
8788 SysUtils.Abort;
8889 end;
8990 finally
90- FreeAndNil(st);
91+ FreeAndNil(lta);
9192 end;
9293 FIsDone := true;
9394 end;
@@ -118,4 +119,3 @@
118119 end;
119120
120121 end.
121-
--- trunk/src/w_LargeTextViewer.pas (revision 262)
+++ trunk/src/w_LargeTextViewer.pas (revision 263)
@@ -13,15 +13,15 @@
1313 Forms,
1414 Dialogs,
1515 Grids,
16+ ExtCtrls,
17+ ComCtrls,
18+ Menus,
19+ ActnList,
1620 c_dzVirtualStringGrid,
1721 u_dzTranslator,
1822 u_TextFileIndexer,
1923 u_dzNamedThread,
20- u_dzFileStreams,
21- ExtCtrls,
22- ComCtrls,
23- Menus,
24- ActnList;
24+ u_dzFileStreams;
2525
2626 type
2727 TIndexerThread = class(TNamedThread)
@@ -127,6 +127,7 @@
127127 if Assigned(FIndexer) then
128128 FIndexer.Abort;
129129 FreeAndNil(FIndexThread);
130+ FreeAndNil(FIndexer);
130131 inherited;
131132 end;
132133
@@ -144,7 +145,7 @@
144145
145146 procedure Tf_LargeTextViewer.UpdateCurrentLineNo;
146147 begin
147- TheStatusBar.Panels[1].Text := Format(_('Current line: %d'), [sg_Display.Row + sg_Display.FixedRows + 1]);
148+ TheStatusBar.Panels[1].Text := Format(_('Current line: %s'), [FormatFloat('#,###,###,###,###,##0', sg_Display.Row + sg_Display.FixedRows + 1)]);
148149 end;
149150
150151 procedure Tf_LargeTextViewer.act_LineCopyExecute(Sender: TObject);
@@ -221,7 +222,7 @@
221222 _State: TGridDrawState; var _Text: string; var _HAlign: TAlignment; var _VAlign: TdzCellVertAlign;
222223 _Font: TFont; var _Color: TColor);
223224 begin
224- _Text := IntToStr(_Row - (_Sender as TdzVirtualStringGrid).FixedRows + 1);
225+ _Text := FormatFloat('#,###,###,###,###,##0', _Row - (_Sender as TdzVirtualStringGrid).FixedRows + 1);
225226 _HAlign := taRightJustify;
226227 end;
227228
@@ -244,9 +245,9 @@
244245 sg_Display.RowCount := LineCount;
245246 if FIndexer.isDone then begin
246247 tim_Update.Enabled := False;
247- TheStatusBar.Panels[0].Text := Format(_('Total lines: %d'), [LineCount]);
248+ TheStatusBar.Panels[0].Text := Format(_('Total lines: %s'), [FormatFloat('#,###,###,###,###,##0', LineCount)]);
248249 end else
249- TheStatusBar.Panels[0].Text := Format(_('Indexing (%d lines)'), [LineCount]);
250+ TheStatusBar.Panels[0].Text := Format(_('Indexing (%s lines)'), [FormatFloat('#,###,###,###,###,##0', LineCount)]);
250251 end;
251252
252253 end.
--- trunk/src/w_Search.pas (revision 262)
+++ trunk/src/w_Search.pas (revision 263)
@@ -38,58 +38,119 @@
3838
3939 uses
4040 StrUtils,
41- JclUnicode,
4241 u_dzVclUtils;
4342
44-///<summary>
45-/// This is the Boyer-Moore-Horspool text searching algorithm taken from
46-/// http://users.dcc.uchile.cl/~rbaeza/handbook/algs/7/713b.srch.p.html
47-/// Modified to work with characters > chr(127) (It does not support unicode though.)
48-/// and take an offset where to start.
49-/// Also, it uses Exit rather than a boolean variable to terminate the while loop.
50-/// @param Pattern is the string to search for
51-/// @param Text is the string to search in </summary
43+type
44+ ITextBuffer = interface ['{8B4A019A-99CA-4E86-864D-D1E9E6020648}']
45+ function GetChar(_Idx: Int64): Char;
46+ function GetString(_Idx: Int64; _Len: integer): string;
47+ function GetLength: Int64;
48+ end;
5249
53-function BMHSearch(_Pattern: string; _Text: string; _Offset: Integer = 0): Integer;
54-const
55- MaxChar = Ord(High(Char));
56-var
57- i: Integer;
58- PatternLen, TextLen: Integer;
59- PatternIdx, TextIdx: Integer;
60- skip: array of Integer;
50+//type
51+// TTextBuffer = class
52+// private
53+// function GetChar(_Idx: Int64): char;
54+// function GetLength: Int64;
55+// public
56+// constructor Create(const _fn: string);
57+// destructor Destroy;
58+// end;
59+
60+type
61+ TStringBuffer = class(TInterfacedObject, ITextBuffer)
62+ private
63+ FText: string;
64+ function GetChar(_Idx: Int64): Char;
65+ function GetString(_Idx: Int64; _Len: integer): string;
66+ function GetLength: Int64;
67+ public
68+ constructor Create(const _Text: string);
69+ end;
70+
71+{ TStringBuffer }
72+
73+constructor TStringBuffer.Create(const _Text: string);
6174 begin
62- PatternLen := Length(_Pattern);
63- if PatternLen = 0 then begin
64- Result := 1;
65- Exit; //=>
75+ inherited Create;
76+ FText := _Text;
77+end;
78+
79+function TStringBuffer.GetChar(_Idx: Int64): Char;
80+begin
81+ Result := FText[_Idx];
82+end;
83+
84+function TStringBuffer.GetLength: Int64;
85+begin
86+ Result := Length(FText);
87+end;
88+
89+function TStringBuffer.GetString(_Idx: Int64; _Len: integer): string;
90+begin
91+ Result := Copy(FText, _Idx, _Len);
92+end;
93+
94+type
95+ TBMSearch = class
96+ private
97+ FSkip: array of integer;
98+ FPatternLen: integer;
99+ FPattern: string;
100+ public
101+ constructor Create(const _Pattern: string);
102+ function Find(_Text: ITextBuffer; var _Offset: Int64): Boolean;
66103 end;
67104
68- Result := 0;
105+{ TBMSearch }
69106
70- SetLength(skip, MaxChar);
71- for i := 0 to MaxChar do
72- skip[i] := PatternLen; {*** Preprocessing ***}
73- for i := 1 to PatternLen - 1 do
74- skip[Ord(_Pattern[i])] := PatternLen - i;
107+constructor TBMSearch.Create(const _Pattern: string);
108+var
109+ i: integer;
110+begin
111+ FPattern := _Pattern;
112+ FPatternLen := Length(_Pattern);
113+ if FPatternLen = 0 then
114+ Exit;
75115
76- i := PatternLen + _Offset;
77- TextLen := Length(_Text); {*** Search ***}
78- while i <= TextLen do begin
116+ SetLength(FSkip, integer(High(Char)) + 1);
117+ for i := Low(FSkip) to High(FSkip) do
118+ FSkip[i] := FPatternLen;
119+ for i := 1 to FPatternLen - 1 do
120+ FSkip[integer(_Pattern[i])] := FPatternLen - i;
121+end;
122+
123+function TBMSearch.Find(_Text: ITextBuffer; var _Offset: Int64): Boolean;
124+var
125+ i: Int64;
126+ TextLen: Int64;
127+ TextIdx: Int64;
128+ PatternIdx: integer;
129+ s: string;
130+begin
131+ Result := False;
132+ if FPatternLen = 0 then
133+ Exit;
134+
135+ i := FPatternLen + (_Offset);
136+ TextLen := _Text.GetLength;
137+ while (not Result) and (i <= TextLen) do begin
79138 TextIdx := i;
80- PatternIdx := PatternLen;
81- while (PatternIdx >= 1) do
82- if _Text[TextIdx] <> _Pattern[PatternIdx] then
83- PatternIdx := -1
84- else begin
139+ PatternIdx := FPatternLen;
140+ while (PatternIdx >= 1) do begin
141+ if _Text.GetChar(TextIdx) = FPattern[PatternIdx] then begin
85142 PatternIdx := PatternIdx - 1;
86143 TextIdx := TextIdx - 1;
144+ end else
145+ PatternIdx := -1;
146+ if PatternIdx = 0 then begin
147+ _Offset := TextIdx;
148+ s := _Text.GetString(_Offset, FPatternLen);
149+ Result := True;
150+ Exit;
87151 end;
88- if PatternIdx = 0 then begin
89- Result := TextIdx + 1;
90- Exit; //=>
152+ i := i + FSkip[integer(_Text.GetChar(i))];
91153 end;
92- i := i + skip[Ord(_Text[i])];
93154 end;
94155 end;
95156
@@ -128,23 +189,17 @@
128189 procedure Tf_Search.b_FindClick(Sender: TObject);
129190 var
130191 Pattern: string;
131- Search: TUTBMSearch;
132- Offset: Integer;
133- Start: Integer;
134- Stop: Integer;
135- Text: WideString;
136- StartP: PWideChar;
192+ Search: TBMSearch;
193+ Offset: Int64;
194+ Text: ITextBuffer;
137195 begin
138196 Pattern := ed_Pattern.Text;
139- Search := TUTBMSearch.Create(nil);
197+ Search := TBMSearch.Create(Pattern);
140198 try
141- Search.FindPrepare(Pattern, [sfWholeWordOnly]);
142- Offset := m_Text.SelStart + m_Text.SelLength;
143- Text := m_Text.Lines.Text;
144- StartP := @Text[1];
145- Inc(StartP, Offset);
146- if Search.FindFirst(StartP, Start, Stop) then begin
147- m_Text.SelStart := Start + Offset;
199+ Offset := m_Text.SelStart + m_Text.SelLength + 1;
200+ Text := TStringBuffer.Create(m_Text.Lines.Text);
201+ if Search.Find(Text, Offset) then begin
202+ m_Text.SelStart := Offset;
148203 m_Text.SelLength := Length(Pattern);
149204 end;
150205 finally
@@ -157,4 +212,3 @@
157212 end;
158213
159214 end.
160-
Show on old repository browser