Faster Pos(ansistring).

This commit is contained in:
Rika Ichinose 2025-02-08 11:05:12 +03:00 committed by Michael Van Canneyt
parent 6631f83ccf
commit 66d7408b3d

View File

@ -832,29 +832,45 @@ end;
{$endif FPC_HAS_ANSISTR_COPY}
{$if not defined(FPC_HAS_POS_SHORTSTR_ANSISTR)
or not defined(FPC_HAS_POS_ANSISTR_ANSISTR)}
function Find(needle : PByte; nNeedle : SizeUint; haystack : PByte; nHaystack : SizeUint): SizeInt;
var
p,d,pmaxplus1,iNeedle : SizeUint;
begin
p:=0;
if SizeUint(nNeedle-1)<nHaystack then { (nNeedle > 0) and (nNeedle <= nHaystack) }
begin
pmaxplus1:=nHaystack-nNeedle+1;
iNeedle:=0;
repeat
if iNeedle=0 then
iNeedle:=nNeedle;
dec(iNeedle);
d:=IndexByte(haystack[p+iNeedle],pmaxplus1-p,needle[iNeedle])+1;
inc(p,d);
until (d=0) or (CompareByte(haystack[p-1],needle^,nNeedle)=0);
if d=0 then
p:=0;
end;
result:=SizeInt(p)-1;
end;
{$endif need Find}
{$ifndef FPC_HAS_POS_SHORTSTR_ANSISTR}
{$define FPC_HAS_POS_SHORTSTR_ANSISTR}
Function Pos(Const Substr : ShortString; Const Source : RawByteString; Offset : Sizeint = 1) : SizeInt;
var
i,MaxLen,nsource,nsub,d : SizeInt;
nsource : SizeInt;
begin
Pos:=0;
nsource:=Length(Source);
nsub:=Length(Substr);
if (nsub>0) and (Offset>0) and (Offset<=nsource) then
begin
MaxLen:=nsource-nsub+1;
i:=Offset;
while (i<=MaxLen) do
begin
d:=IndexByte(Source[i],MaxLen-i+1,byte(Substr[1]));
if d<0 then
exit;
if CompareByte(Substr[1],Source[i+d],nsub)=0 then
exit(i+d);
i:=i+d+1;
end;
end;
result:=0;
dec(Offset);
if SizeUint(Offset)<SizeUint(nsource) then { (Offset >= 0) and (Offset < nsource) }
result:=Find(@Substr[1],length(Substr),pointer(Source)+Offset,nsource-Offset)+1;
if result>0 then
inc(result,Offset);
end;
{$endif FPC_HAS_POS_SHORTSTR_ANSISTR}
@ -863,25 +879,15 @@ end;
{$define FPC_HAS_POS_ANSISTR_ANSISTR}
Function Pos(Const Substr : RawByteString; Const Source : RawByteString; Offset : Sizeint = 1) : SizeInt;
var
i,MaxLen,nsource,nsub,d : SizeInt;
nsource : SizeInt;
begin
Pos:=0;
nsource:=Length(Source);
nsub:=Length(Substr);
if (nsub>0) and (Offset>0) and (Offset<=nsource) then
begin
MaxLen:=nsource-nsub+1;
i:=Offset;
while (i<=MaxLen) do
begin
d:=IndexByte(Source[i],MaxLen-i+1,byte(Substr[1]));
if d<0 then
exit;
if CompareByte(Substr[1],Source[i+d],nsub)=0 then
exit(i+d);
i:=i+d+1;
end;
end;
result:=0;
dec(Offset);
if SizeUint(Offset)<SizeUint(nsource) then { (Offset >= 0) and (Offset < nsource) }
result:=Find(pointer(Substr),length(Substr),pointer(Source)+Offset,nsource-Offset)+1;
if result>0 then
inc(result,Offset);
end;
{$endif FPC_HAS_POS_ANSISTR_ANSISTR}