Browse Source

Faster Pos(ansistring).

Rika Ichinose 5 months ago
parent
commit
66d7408b3d
1 changed files with 40 additions and 34 deletions
  1. 40 34
      rtl/inc/astrings.inc

+ 40 - 34
rtl/inc/astrings.inc

@@ -832,29 +832,45 @@ end;
 {$endif FPC_HAS_ANSISTR_COPY}
 {$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}
 {$ifndef FPC_HAS_POS_SHORTSTR_ANSISTR}
 {$define FPC_HAS_POS_SHORTSTR_ANSISTR}
 {$define FPC_HAS_POS_SHORTSTR_ANSISTR}
 Function Pos(Const Substr : ShortString; Const Source : RawByteString; Offset : Sizeint = 1) : SizeInt;
 Function Pos(Const Substr : ShortString; Const Source : RawByteString; Offset : Sizeint = 1) : SizeInt;
 var
 var
-  i,MaxLen,nsource,nsub,d : SizeInt;
+  nsource : SizeInt;
 begin
 begin
-  Pos:=0;
   nsource:=Length(Source);
   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;
 end;
 {$endif FPC_HAS_POS_SHORTSTR_ANSISTR}
 {$endif FPC_HAS_POS_SHORTSTR_ANSISTR}
 
 
@@ -863,25 +879,15 @@ end;
 {$define FPC_HAS_POS_ANSISTR_ANSISTR}
 {$define FPC_HAS_POS_ANSISTR_ANSISTR}
 Function Pos(Const Substr : RawByteString; Const Source : RawByteString; Offset : Sizeint = 1) : SizeInt;
 Function Pos(Const Substr : RawByteString; Const Source : RawByteString; Offset : Sizeint = 1) : SizeInt;
 var
 var
-  i,MaxLen,nsource,nsub,d : SizeInt;
+  nsource : SizeInt;
 begin
 begin
-  Pos:=0;
   nsource:=Length(Source);
   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;
 end;
 {$endif FPC_HAS_POS_ANSISTR_ANSISTR}
 {$endif FPC_HAS_POS_ANSISTR_ANSISTR}