mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
FIX: Viewer - Slow case insensitive backward search with single byte encoding
(cherry picked from commit cb9b79a26d)
This commit is contained in:
parent
d00f8b7b7c
commit
b0ca10d89b
2 changed files with 77 additions and 1 deletions
|
|
@ -2521,7 +2521,7 @@ begin
|
|||
if bTextFound then FLastSearchPos := PAnsiAddr - ViewerControl.GetDataAdr;
|
||||
end
|
||||
// Using very slow search algorithm
|
||||
else if (ViewerControl.Encoding in ViewerEncodingMultiByte) or bSearchBackwards then
|
||||
else if (ViewerControl.Encoding in [veUtf32le, veUtf32be]) then
|
||||
begin
|
||||
PAdr := ViewerControl.FindUtf8Text(FLastSearchPos, sSearchTextU,
|
||||
FFindDialog.cbCaseSens.Checked,
|
||||
|
|
@ -2529,6 +2529,16 @@ begin
|
|||
bTextFound := (PAdr <> PtrInt(-1));
|
||||
if bTextFound then FLastSearchPos := PAdr;
|
||||
end
|
||||
// Using special case insensitive single byte encoding search algorithm
|
||||
else if bSearchBackwards then
|
||||
begin
|
||||
RecodeTable:= InitRecodeTable(ViewerControl.EncodingName, FFindDialog.cbCaseSens.Checked);
|
||||
PAnsiAddr := PosMemA(ViewerControl.GetDataAdr, ViewerControl.FileSize,
|
||||
FLastSearchPos, sSearchTextA,
|
||||
FFindDialog.cbCaseSens.Checked, bSearchBackwards, RecodeTable);
|
||||
bTextFound := (PAnsiAddr <> Pointer(-1));
|
||||
if bTextFound then FLastSearchPos := PAnsiAddr - ViewerControl.GetDataAdr;
|
||||
end
|
||||
// Using very fast Boyer–Moore search algorithm
|
||||
else begin
|
||||
RecodeTable:= InitRecodeTable(ViewerControl.EncodingName, FFindDialog.cbCaseSens.Checked);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ unit uFindMmap;
|
|||
|
||||
interface
|
||||
|
||||
uses
|
||||
uFindByrMr;
|
||||
|
||||
type
|
||||
TAbortFunction = function: Boolean of object;
|
||||
|
||||
|
|
@ -45,6 +48,10 @@ function PosMemU(pDataAddr: PChar; iDataLength, iStartPos: PtrInt;
|
|||
function PosMemW(pDataAddr: PChar; iDataLength, iStartPos: PtrInt;
|
||||
const sSearchText: String; bSearchBackwards, bLittleEndian: Boolean): Pointer;
|
||||
|
||||
function PosMemA(pDataAddr: PChar; iDataLength, iStartPos: PtrInt;
|
||||
const sSearchText: String; bCaseSensitive, bSearchBackwards: Boolean;
|
||||
RecodeTable: TRecodeTable): Pointer;
|
||||
|
||||
{en
|
||||
Searches a file for a string using memory mapping.
|
||||
|
||||
|
|
@ -278,6 +285,65 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function PosMemA(pDataAddr: PChar; iDataLength, iStartPos: PtrInt;
|
||||
const sSearchText: String; bCaseSensitive, bSearchBackwards: Boolean;
|
||||
RecodeTable: TRecodeTable): Pointer;
|
||||
var
|
||||
SearchTextLength: Integer;
|
||||
|
||||
function sPos2(pAdr: PChar):Boolean; inline;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
for i := 1 to SearchTextLength do
|
||||
begin
|
||||
case bCaseSensitive of
|
||||
False: if Chr(RecodeTable[Ord(pAdr^)]) <> Chr(RecodeTable[Ord(sSearchText[i])]) then Exit;
|
||||
True : if pAdr^ <> sSearchText[i] then Exit;
|
||||
end;
|
||||
Inc(pAdr);
|
||||
end;
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
var
|
||||
pCurrentAddr, pEndAddr: PAnsiChar;
|
||||
begin
|
||||
Result := Pointer(-1);
|
||||
|
||||
SearchTextLength := Length(sSearchText);
|
||||
if (SearchTextLength <= 0) or (iDataLength <= 0) then
|
||||
Exit;
|
||||
|
||||
pCurrentAddr := pDataAddr + iStartPos;
|
||||
pEndAddr := pDataAddr + iDataLength - SearchTextLength;
|
||||
|
||||
if bSearchBackwards and (pCurrentAddr > pEndAddr) then
|
||||
// Move to the first possible position for searching backwards.
|
||||
pCurrentAddr := pEndAddr;
|
||||
|
||||
if (pEndAddr < pDataAddr) or (pCurrentAddr < pDataAddr) or (pCurrentAddr > pEndAddr) then
|
||||
Exit;
|
||||
|
||||
while True do
|
||||
begin
|
||||
if (pCurrentAddr > pEndAddr) or (pCurrentAddr < pDataAddr) then
|
||||
Exit;
|
||||
|
||||
if sPos2(pCurrentAddr) then
|
||||
begin
|
||||
Result := pCurrentAddr;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
case bSearchBackwards of
|
||||
False: Inc(pCurrentAddr);
|
||||
True : Dec(pCurrentAddr);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function FindMmap(const sFileName: String; const sFindData: String;
|
||||
bCase: Boolean; Abort: TAbortFunction): Integer;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue