浏览代码

UPD: Using very fast Boyer–Moore search algorithm in Viewer when possible

Alexander Koblov 11 年之前
父节点
当前提交
8bd1fd1b42
共有 2 个文件被更改,包括 22 次插入4 次删除
  1. 7 0
      components/viewer/viewercontrol.pas
  2. 15 4
      src/fviewer.pas

+ 7 - 0
components/viewer/viewercontrol.pas

@@ -113,6 +113,8 @@ type
                      veUtf32le,  // = ucs4le
                      veUtf32le,  // = ucs4le
                      veUtf32be); // = ucs4be
                      veUtf32be); // = ucs4be
 
 
+  TViewerEncodings = set of TViewerEncoding;
+
 const
 const
   ViewerEncodingsNames: array [TViewerEncoding] of string =
   ViewerEncodingsNames: array [TViewerEncoding] of string =
                    ('Auto-detect',
                    ('Auto-detect',
@@ -147,6 +149,11 @@ const
                     'UTF-32LE',
                     'UTF-32LE',
                     'UTF-32BE');
                     'UTF-32BE');
 
 
+const
+  ViewerEncodingMultiByte: TViewerEncodings = [
+    veUtf8, veUtf8bom, veUcs2le, veUcs2be,
+    veUtf16le, veUtf16be, veUtf32le, veUtf32be];
+
 type
 type
 
 
   { TViewerControl }
   { TViewerControl }

+ 15 - 4
src/fviewer.pas

@@ -313,7 +313,7 @@ implementation
 uses
 uses
   FileUtil, IntfGraphics, Math, uLng, uShowMsg, uGlobs, LCLType, LConvEncoding,
   FileUtil, IntfGraphics, Math, uLng, uShowMsg, uGlobs, LCLType, LConvEncoding,
   DCClassesUtf8, uFindMmap, DCStrUtils, uDCUtils, LCLIntf, uDebug, uHotkeyManager,
   DCClassesUtf8, uFindMmap, DCStrUtils, uDCUtils, LCLIntf, uDebug, uHotkeyManager,
-  uConvEncoding, DCBasicTypes, DCOSUtils, uOSUtils;
+  uConvEncoding, DCBasicTypes, DCOSUtils, uOSUtils, uFindByrMr;
 
 
 const
 const
   HotkeysCategory = 'Viewer';
   HotkeysCategory = 'Viewer';
@@ -1996,6 +1996,7 @@ var
   sSearchTextU: UTF8String;
   sSearchTextU: UTF8String;
   sSearchTextA: AnsiString;
   sSearchTextA: AnsiString;
   iSearchParameter: Integer;
   iSearchParameter: Integer;
+  RecodeTable: TRecodeTable;
 begin
 begin
   // in first use create dialog
   // in first use create dialog
   if not Assigned(FFindDialog) then
   if not Assigned(FFindDialog) then
@@ -2055,8 +2056,8 @@ begin
       end;
       end;
 
 
       sSearchTextA:= ViewerControl.ConvertFromUTF8(sSearchTextU);
       sSearchTextA:= ViewerControl.ConvertFromUTF8(sSearchTextU);
-      // Using fast search algorithm if ASCII or case insensitive
-      if FFindDialog.cbCaseSens.Checked or TextIsASCII(sSearchTextA) then
+      // Using standard search algorithm if case insensitive and multibyte
+      if FFindDialog.cbCaseSens.Checked and (ViewerControl.Encoding in ViewerEncodingMultiByte) then
       begin
       begin
         PAnsiAddr := PosMem(ViewerControl.GetDataAdr, ViewerControl.FileSize,
         PAnsiAddr := PosMem(ViewerControl.GetDataAdr, ViewerControl.FileSize,
                             FLastSearchPos, sSearchTextA,
                             FLastSearchPos, sSearchTextA,
@@ -2064,12 +2065,22 @@ begin
         bTextFound := (PAnsiAddr <> Pointer(-1));
         bTextFound := (PAnsiAddr <> Pointer(-1));
         if bTextFound then FLastSearchPos := PAnsiAddr - ViewerControl.GetDataAdr;
         if bTextFound then FLastSearchPos := PAnsiAddr - ViewerControl.GetDataAdr;
       end
       end
-      else begin
+      // Using very slow search algorithm
+      else if (ViewerControl.Encoding in ViewerEncodingMultiByte) then
+      begin
         PAdr := ViewerControl.FindUtf8Text(FLastSearchPos, sSearchTextU,
         PAdr := ViewerControl.FindUtf8Text(FLastSearchPos, sSearchTextU,
                                            FFindDialog.cbCaseSens.Checked,
                                            FFindDialog.cbCaseSens.Checked,
                                            bSearchBackwards);
                                            bSearchBackwards);
         bTextFound := (PAdr <> PtrInt(-1));
         bTextFound := (PAdr <> PtrInt(-1));
         if bTextFound then FLastSearchPos := PAdr;
         if bTextFound then FLastSearchPos := PAdr;
+      end
+      // Using very fast Boyer–Moore search algorithm
+      else begin
+        RecodeTable:= InitRecodeTable(ViewerControl.EncodingName, FFindDialog.cbCaseSens.Checked);
+        PAdr := PosMemBoyerMur(ViewerControl.GetDataAdr + FLastSearchPos,
+                               ViewerControl.FileSize, sSearchTextA, RecodeTable);
+        bTextFound := (PAdr <> PtrInt(-1));
+        if bTextFound then FLastSearchPos := PAdr;
       end;
       end;
 
 
       if bTextFound then
       if bTextFound then