Browse Source

Faster Insert(ansi/unicodestring).

Rika Ichinose 1 year ago
parent
commit
801e14c33b
3 changed files with 54 additions and 35 deletions
  1. 32 16
      rtl/inc/astrings.inc
  2. 22 15
      rtl/inc/ustrings.inc
  3. 0 4
      tests/webtbs/tw28850.pp

+ 32 - 16
rtl/inc/astrings.inc

@@ -1331,30 +1331,46 @@ end;
 
 Procedure {$ifdef VER3_0}Insert{$else}fpc_ansistr_insert{$endif}(Const Source : RawByteString; Var S : RawByteString; Index : SizeInt);
 var
+  LS,LSource : SizeInt;
+{$ifdef jvm}
   Temp : RawByteString;
-  LS : SizeInt;
-  cp : TSystemCodePage;
+{$else}
+  selfinsert : boolean;
+  srcp : PAnsiChar;
+{$endif}
 begin
-  If Length(Source)=0 then
+  If Source='' then
    exit;
-  if index <= 0 then
-   index := 1;
-  Ls:=Length(S);
-  if index > LS then
-   index := LS+1;
+  if S='' then
+    begin
+      S:=Source;
+      exit;
+    end;
+  LSource:={$ifdef jvm}Length(Source){$else}PAnsiRec(Pointer(Source)-AnsiFirstOff)^.Len{$endif};
+  LS:={$ifdef jvm}Length(S){$else}PAnsiRec(Pointer(S)-AnsiFirstOff)^.Len{$endif};
   Dec(Index);
-  SetLength(Temp,Length(Source)+LS);
-  if length(S)<>0 then
-    cp:=TranslatePlaceholderCP(StringCodePage(S))
-  else
-    cp:=TranslatePlaceholderCP(StringCodePage(Source));
-  SetCodePage(Temp,cp,false);
+  if index < 0 then
+   index := 0;
+  if index > LS then
+   index := LS;
+{$ifdef jvm}
+  SetLength(Temp,LSource+LS);
+  SetCodePage(Temp,StringCodePage(S),false);
   If Index>0 then
     fpc_pchar_ansistr_intern_charmove(PAnsiChar(S),0,Temp,0,Index);
-  fpc_pchar_ansistr_intern_charmove(PAnsiChar(Source),0,Temp,Index,Length(Source));
+  fpc_pchar_ansistr_intern_charmove(PAnsiChar(Source),0,Temp,Index,LSource);
   If (LS-Index)>0 then
-    fpc_pchar_ansistr_intern_charmove(PAnsiChar(S),Index,Temp,Length(Source)+Index,LS-Index);
+    fpc_pchar_ansistr_intern_charmove(PAnsiChar(S),Index,Temp,LSource+Index,LS-Index);
   S:=Temp;
+{$else}
+  selfinsert:=Pointer(Source)=Pointer(S);
+  SetLength(S,LS+LSource);
+  Move(PAnsiChar(Pointer(S))[Index],PAnsiChar(Pointer(S))[Index+LSource],(LS-Index)*SizeOf(AnsiChar));
+  srcp:=Pointer(Source);
+  if selfinsert then
+    srcp:=Pointer(S);
+  Move(srcp^,PAnsiChar(Pointer(S))[Index],LSource*SizeOf(AnsiChar));
+{$endif}
 end;
 
 

+ 22 - 15
rtl/inc/ustrings.inc

@@ -1327,24 +1327,31 @@ end;
 {$define FPC_HAS_INSERT_UNICODESTR}
 Procedure {$ifdef VER3_0}Insert{$else}fpc_unicodestr_insert{$endif}(Const Source : UnicodeString; Var S : UnicodeString; Index : SizeInt);
 var
-  Temp : UnicodeString;
-  LS : SizeInt;
+  LS,LSource : SizeInt;
+  selfinsert : boolean;
+  srcp : PUnicodeChar;
 begin
-  If Length(Source)=0 then
+  If Source='' then
    exit;
-  if index <= 0 then
-   index := 1;
-  Ls:=Length(S);
-  if index > LS then
-   index := LS+1;
+  if S='' then
+    begin
+      S:=Source;
+      exit;
+    end;
+  LSource:=PUnicodeRec(Pointer(Source)-UnicodeFirstOff)^.Len;
+  LS:=PUnicodeRec(Pointer(S)-UnicodeFirstOff)^.Len;
   Dec(Index);
-  SetLength(Temp,Length(Source)+LS);
-  If Index>0 then
-    move (PUnicodeChar(S)^,PUnicodeChar(Temp)^,Index*sizeof(UnicodeChar));
-  Move (PUnicodeChar(Source)^,PUnicodeChar(Temp)[Index],Length(Source)*sizeof(UnicodeChar));
-  If (LS-Index)>0 then
-    Move(PUnicodeChar(S)[Index],PUnicodeChar(temp)[Length(Source)+index],(LS-Index)*sizeof(UnicodeChar));
-  S:=Temp;
+  if index < 0 then
+   index := 0;
+  if index > LS then
+   index := LS;
+  selfinsert:=Pointer(Source)=Pointer(S);
+  SetLength(S,LSource+LS);
+  Move(PUnicodeChar(Pointer(S))[Index],PUnicodeChar(Pointer(S))[Index+LSource],(LS-Index)*sizeof(UnicodeChar));
+  srcp:=Pointer(Source);
+  if selfinsert then
+    srcp:=Pointer(S);
+  Move(srcp^,PUnicodeChar(Pointer(S))[Index],LSource*SizeOf(UnicodeChar));
 end;
 {$endif FPC_HAS_INSERT_UNICODESTR}
 

+ 0 - 4
tests/webtbs/tw28850.pp

@@ -11,10 +11,6 @@ begin
   { if the destination is empty, insert must create a new string
     with the same code page as the source }
   Insert(s1, s2, 1);
-  if StringRefCount(s1)<>1 then
-    halt(1);
-  if StringRefCount(s2)<>1 then
-    halt(2);
   if stringcodepage(s2)<>stringcodepage(s1) then
     halt(3);
 end.