mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-02 15:42:08 +02:00
LazUtils: Optimize PosI(), the case-insensitive version of Pos().
git-svn-id: trunk@64616 -
This commit is contained in:
parent
0d468e1564
commit
350c9735d0
@ -423,7 +423,7 @@ begin
|
|||||||
Dec(ExtLen);
|
Dec(ExtLen);
|
||||||
end;
|
end;
|
||||||
if ExtLen <> FnExtLen then
|
if ExtLen <> FnExtLen then
|
||||||
exit(False); // Ext has different length than Filename
|
exit(False); // Ext has different length than Filename's extension
|
||||||
// compare extensions
|
// compare extensions
|
||||||
if CaseSensitive then
|
if CaseSensitive then
|
||||||
Result := StrLComp(ExtP, FnP, ExtLen) = 0
|
Result := StrLComp(ExtP, FnP, ExtLen) = 0
|
||||||
@ -460,7 +460,7 @@ begin
|
|||||||
Dec(ExtLen);
|
Dec(ExtLen);
|
||||||
end;
|
end;
|
||||||
if ExtLen <> FnExtLen then
|
if ExtLen <> FnExtLen then
|
||||||
continue; // Ext has different length than Filename
|
continue; // Ext has different length than Filename's extension
|
||||||
// compare extensions
|
// compare extensions
|
||||||
if CaseSensitive then
|
if CaseSensitive then
|
||||||
Result := StrLComp(ExtP, FnP, ExtLen) = 0
|
Result := StrLComp(ExtP, FnP, ExtLen) = 0
|
||||||
|
@ -138,32 +138,33 @@ end;
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
function PosI(const SubStr, S: string): integer;
|
function PosI(const SubStr, S: string): integer;
|
||||||
// A case-insensitive version of Pos().
|
// A case-insensitive optimized version of Pos(). Comparison Supports only ASCII.
|
||||||
// Note: StrUtils has ContainsText but its implementation is VERY slow.
|
// Can be used instead of common but slower Pos(UpperCase(SubStr),UpperCase(S));
|
||||||
var
|
var
|
||||||
Len1, Len2, Cnt1, Cnt2: integer;
|
SubLen, SLen: integer;
|
||||||
SubFirst: Char;
|
SubP, SP, SPEnd: PChar;
|
||||||
|
SubBP: PByte absolute SubP;
|
||||||
|
SBP: PByte absolute SP;
|
||||||
begin
|
begin
|
||||||
Len1 := Length(SubStr);
|
|
||||||
Len2 := Length(S);
|
|
||||||
if (Len1 = 0) or (Len1 > Len2) then
|
|
||||||
Exit(0);
|
|
||||||
SubFirst := LowerCase(SubStr[1]);
|
|
||||||
Result := 0;
|
Result := 0;
|
||||||
for Cnt1 := 1 to Len2-Len1+1 do
|
SubLen := Length(SubStr);
|
||||||
begin // Outer loop finds the first matching character.
|
SLen := Length(S);
|
||||||
if LowerCase(S[Cnt1]) = SubFirst then
|
if (SubLen = 0) or (SubLen > SLen) then
|
||||||
begin // Maybe a start of the substring.
|
Exit;
|
||||||
Result := Cnt1;
|
SubP := @SubStr[1];
|
||||||
for Cnt2 := 2 to Len1 do
|
SP := @S[1];
|
||||||
if LowerCase(S[Cnt1+Cnt2-1]) <> LowerCase(SubStr[Cnt2]) then
|
SPEnd := SP + SLen - SubLen;
|
||||||
begin
|
while True do
|
||||||
Result := 0; // No match
|
begin
|
||||||
break;
|
while (SP <= SPEnd) and ((SubBP^ xor SBP^) and $DF <> 0) do
|
||||||
end;
|
Inc(SP); // Not equal even after removing the $20 upper/lower diff
|
||||||
end;
|
if SP > SPEnd then
|
||||||
if Result > 0 then
|
Break;
|
||||||
break;
|
// Now they may be equal but could be false positive
|
||||||
|
if (Char(SBP^ and $DF) in ['A'..'Z']) or (SP^ = SubP^) then
|
||||||
|
if StrLIComp(SubP+1, SP+1, SubLen-1) = 0 then // First char matched
|
||||||
|
Exit(SP - @S[1] + 1); // .. and also the rest of it
|
||||||
|
Inc(SP);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user