Browse Source

Let “Trim”s return string uncopied.

Rika Ichinose 1 year ago
parent
commit
ff9fe851fb

+ 35 - 36
rtl/objpas/sysutils/syshelps.inc

@@ -3,9 +3,12 @@
   TStringHelper
   TStringHelper
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
 
 
+{$ifdef IS_ANSISTRINGHELPER}
+type
+  TTrimMode = {$push} {$scopedenums on} (Left, Right, Both) {$pop};
+{$endif}
 
 
-{$IFNDEF IS_SHORTSTRINGHELPER}
-{$IFNDEF IS_UNICODESTRINGHELPER}
+{$IF not defined(IS_SHORTSTRINGHELPER) and not defined(IS_UNICODESTRINGHELPER)}
 // Doubles with (wide/ansi)string...
 // Doubles with (wide/ansi)string...
 Function HaveChar(AChar : TStringChar; const AList: array of TStringChar) : Boolean;
 Function HaveChar(AChar : TStringChar; const AList: array of TStringChar) : Boolean;
 
 
@@ -14,15 +17,32 @@ Var
 
 
 begin
 begin
   I:=0;
   I:=0;
-  Result:=False;
-  While (Not Result) and (I<Length(AList)) do
-    begin
-    Result:=(AList[i]=AChar);
+  while (I<=High(AList)) and (AList[I]<>AChar) do
     Inc(I);
     Inc(I);
-    end;
+  Result:=I<=High(AList);
 end;
 end;
 {$ENDIF}
 {$ENDIF}
-{$ENDIF}
+
+function Trim(const S: TStringType; const ATrimChars: array of TStringChar; mode: TTrimMode): TStringType;
+
+var
+  start, ed, ns: SizeInt;
+
+begin
+  start := 1;
+  ns := System.Length(S);
+  ed := ns;
+  if mode <> TTrimMode.Right then
+    while (start <= ed) and HaveChar(S[start], ATrimChars) do
+      inc(start);
+  if mode <> TTrimMode.Left then
+    while (start <= ed) and HaveChar(S[ed], ATrimChars) do
+      dec(ed);
+  if (start = 1) and (ed = ns) then
+    Result := S
+  else
+    Result := Copy(S, start, ed - start + 1);
+end;
 
 
 function TStringHelper.GetChar(AIndex: SizeInt): TStringChar;
 function TStringHelper.GetChar(AIndex: SizeInt): TStringChar;
 begin
 begin
@@ -1339,7 +1359,10 @@ end;
 
 
 function TStringHelper.Substring(AStartIndex: SizeInt; ALen: SizeInt): TStringType;
 function TStringHelper.Substring(AStartIndex: SizeInt; ALen: SizeInt): TStringType;
 begin
 begin
-  Result:=system.Copy(Self,AStartIndex+1,ALen);
+  if (AStartIndex<=0) and (ALen>=System.Length(Self)) then
+    Result:=Self
+  else
+    Result:=system.Copy(Self,AStartIndex+1,ALen);
 end;
 end;
 
 
 
 
@@ -1443,43 +1466,19 @@ end;
 
 
 function TStringHelper.Trim(const ATrimChars: array of TStringChar): TStringType;
 function TStringHelper.Trim(const ATrimChars: array of TStringChar): TStringType;
 begin
 begin
-  Result:=Self.TrimLeft(ATrimChars).TrimRight(ATrimChars);
+  Result:=SUT.Trim(Self, ATrimChars, TTrimMode.Both);
 end;
 end;
 
 
 
 
 function TStringHelper.TrimLeft(const ATrimChars: array of TStringChar): TStringType;
 function TStringHelper.TrimLeft(const ATrimChars: array of TStringChar): TStringType;
-
-Var
-  I,Len : SizeInt;
-
 begin
 begin
-  I:=1;
-  Len:=Self.Length;
-  While (I<=Len) and HaveChar(Self[i],ATrimChars) do Inc(I);
-  if I=1 then
-    Result:=Self
-  else if I>Len then
-    Result:=''
-  else
-    Result:=system.Copy(Self,I,Len-I+1);
+  Result:=SUT.Trim(Self, ATrimChars, TTrimMode.Left);
 end;
 end;
 
 
 
 
 function TStringHelper.TrimRight(const ATrimChars: array of TStringChar): TStringType;
 function TStringHelper.TrimRight(const ATrimChars: array of TStringChar): TStringType;
-
-Var
-  I,Len : SizeInt;
-
 begin
 begin
-  Len:=Self.Length;
-  I:=Len;
-  While (I>=1) and HaveChar(Self[i],ATrimChars) do Dec(I);
-  if I<1 then
-    Result:=''
-  else if I=Len then
-    Result:=Self
-  else
-    Result:=system.Copy(Self,1,I);
+  Result:=SUT.Trim(Self, ATrimChars, TTrimMode.Right);
 end;
 end;
 
 
 
 

+ 22 - 21
rtl/objpas/sysutils/sysstr.inc

@@ -634,41 +634,42 @@ function AnsiStrUpper(Str: PAnsiChar): PAnsiChar;{$ifdef SYSUTILSINLINE}inline;{
 
 
 {   Trim returns a copy of S with blanks characters on the left and right stripped off   }
 {   Trim returns a copy of S with blanks characters on the left and right stripped off   }
 
 
-Const WhiteSpace = [#0..' '];
+function Trim(const S: ansistring; mode: TTrimMode): ansistring;
+var
+  start, ed, ns: SizeInt;
+begin
+  start := 1;
+  ns := Length(S);
+  ed := ns;
+  if mode <> TTrimMode.Right then
+    while (start <= ed) and (S[start] <= ' ') do
+      inc(start);
+  if mode <> TTrimMode.Left then
+    while (start <= ed) and (S[ed] <= ' ') do
+      dec(ed);
+  if (start = 1) and (ed = ns) then
+    Result := S
+  else
+    Result := Copy(S, start, ed - start + 1);
+end;
 
 
 function Trim(const S: ansistring): ansistring;
 function Trim(const S: ansistring): ansistring;
-var Ofs, Len: integer;
-begin
-  len := Length(S);
-  while (Len>0) and (S[Len] in WhiteSpace) do
-   dec(Len);
-  Ofs := 1;
-  while (Ofs<=Len) and (S[Ofs] in WhiteSpace) do
-   Inc(Ofs);
-  result := Copy(S, Ofs, 1 + Len - Ofs);
+begin
+  result := Trim(S, TTrimMode.Both);
 end ;
 end ;
 
 
 {   TrimLeft returns a copy of S with all blank characters on the left stripped off  }
 {   TrimLeft returns a copy of S with all blank characters on the left stripped off  }
 
 
 function TrimLeft(const S: ansistring): ansistring;
 function TrimLeft(const S: ansistring): ansistring;
-var i,l:integer;
 begin
 begin
-  l := length(s);
-  i := 1;
-  while (i<=l) and (s[i] in whitespace) do
-   inc(i);
-  Result := copy(s, i, l);
+  result := Trim(S, TTrimMode.Left);
 end ;
 end ;
 
 
 {   TrimRight returns a copy of S with all blank characters on the right stripped off  }
 {   TrimRight returns a copy of S with all blank characters on the right stripped off  }
 
 
 function TrimRight(const S: ansistring): ansistring;
 function TrimRight(const S: ansistring): ansistring;
-var l:integer;
 begin
 begin
-  l := length(s);
-  while (l>0) and (s[l] in whitespace) do
-   dec(l);
-  result := copy(s,1,l);
+  result := Trim(S, TTrimMode.Right);
 end ;
 end ;
 
 
 {   QuotedStr returns S quoted left and right and every single quote in S
 {   QuotedStr returns S quoted left and right and every single quote in S

+ 3 - 3
rtl/objpas/sysutils/sysstrh.inc

@@ -104,9 +104,9 @@ function AnsiLastChar(const S: AnsiString): PAnsiChar;
 function AnsiLastChar(const S: UnicodeString): PWideChar;
 function AnsiLastChar(const S: UnicodeString): PWideChar;
 function AnsiStrLastChar(Str: PAnsiChar): PAnsiChar;
 function AnsiStrLastChar(Str: PAnsiChar): PAnsiChar;
 
 
-function Trim(const S: ansistring): ansistring;
-function TrimLeft(const S: ansistring): ansistring;
-function TrimRight(const S: ansistring): ansistring;
+function Trim(const S: ansistring): ansistring; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function TrimLeft(const S: ansistring): ansistring; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function TrimRight(const S: ansistring): ansistring; {$ifdef SYSUTILSINLINE}inline;{$endif}
 function QuotedStr(const S: string): string; {$ifdef SYSUTILSINLINE}inline;{$endif}
 function QuotedStr(const S: string): string; {$ifdef SYSUTILSINLINE}inline;{$endif}
 function AnsiQuotedStr(const S: string; Quote: Char): string;
 function AnsiQuotedStr(const S: string; Quote: Char): string;
 function AnsiDequotedStr(const S: string; AQuote: Char): string;
 function AnsiDequotedStr(const S: string; AQuote: Char): string;

+ 22 - 22
rtl/objpas/sysutils/sysuni.inc

@@ -12,42 +12,42 @@
     *********************************************************************
     *********************************************************************
 }
 }
 
 
+function Trim(const S: unicodestring; mode: TTrimMode): unicodestring;
+  var
+    start, ed, ns: SizeInt;
+  begin
+    start := 1;
+    ns := Length(S);
+    ed := ns;
+    if mode <> TTrimMode.Right then
+      while (start <= ed) and (S[start] <= ' ') do
+        inc(start);
+    if mode <> TTrimMode.Left then
+      while (start <= ed) and (S[ed] <= ' ') do
+        dec(ed);
+    if (start = 1) and (ed = ns) then
+      Result := S
+    else
+      Result := Copy(S, start, ed - start + 1);
+  end;
+
 function Trim(const S: unicodestring): unicodestring;
 function Trim(const S: unicodestring): unicodestring;
-  var 
-    Ofs, Len: sizeint;
   begin
   begin
-    len := Length(S);
-    while (Len>0) and (S[Len]<=' ') do
-     dec(Len);
-    Ofs := 1;
-    while (Ofs<=Len) and (S[Ofs]<=' ') do
-      Inc(Ofs);
-    result := Copy(S, Ofs, 1 + Len - Ofs);
+    result := Trim(S, TTrimMode.Both);
   end;
   end;
 	
 	
 
 
 { TrimLeft returns a copy of S with all blank characters on the left stripped off  }
 { TrimLeft returns a copy of S with all blank characters on the left stripped off  }
 function TrimLeft(const S: unicodestring): unicodestring;
 function TrimLeft(const S: unicodestring): unicodestring;
-  var 
-    i,l:sizeint;
   begin
   begin
-    l := length(s);
-    i := 1;
-    while (i<=l) and (s[i]<=' ') do
-      inc(i);
-    Result := copy(s, i, l);
+    Result := Trim(S, TTrimMode.Left);
   end;
   end;
 	
 	
 
 
 { TrimRight returns a copy of S with all blank characters on the right stripped off  }
 { TrimRight returns a copy of S with all blank characters on the right stripped off  }
 function TrimRight(const S: unicodestring): unicodestring;
 function TrimRight(const S: unicodestring): unicodestring;
-  var 
-	l:sizeint;
   begin
   begin
-    l := length(s);
-    while (l>0) and (s[l]<=' ') do
-      dec(l);
-    result := copy(s,1,l);
+    Result := Trim(S, TTrimMode.Right);
   end;
   end;
 
 
 
 

+ 3 - 3
rtl/objpas/sysutils/sysunih.inc

@@ -15,9 +15,9 @@
 type
 type
   TUnicodeCharArray = array of UnicodeChar;
   TUnicodeCharArray = array of UnicodeChar;
 
 
-function Trim(const S: unicodestring): unicodestring;
-function TrimLeft(const S: unicodestring): unicodestring;
-function TrimRight(const S: unicodestring): unicodestring;
+function Trim(const S: unicodestring): unicodestring; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function TrimLeft(const S: unicodestring): unicodestring; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function TrimRight(const S: unicodestring): unicodestring; {$ifdef SYSUTILSINLINE}inline;{$endif}
 
 
 function UpperCase(const s: UnicodeString): UnicodeString; overload;
 function UpperCase(const s: UnicodeString): UnicodeString; overload;
 function LowerCase(const s: UnicodeString): UnicodeString; overload;
 function LowerCase(const s: UnicodeString): UnicodeString; overload;

+ 22 - 22
rtl/objpas/sysutils/syswide.inc

@@ -17,42 +17,42 @@ begin
     Result := (Ch >= #$D800) and (Ch <= #$DFFF);
     Result := (Ch >= #$D800) and (Ch <= #$DFFF);
 end;
 end;
 
 
+function Trim(const S: widestring; mode: TTrimMode): widestring;
+	var
+	  start, ed, ns: SizeInt;
+	begin
+	  start := 1;
+	  ns := Length(S);
+	  ed := ns;
+	  if mode <> TTrimMode.Right then
+	    while (start <= ed) and (S[start] <= ' ') do
+	      inc(start);
+	  if mode <> TTrimMode.Left then
+	    while (start <= ed) and (S[ed] <= ' ') do
+	      dec(ed);
+	  if (start = 1) and (ed = ns) then
+	    Result := S
+	  else
+	    Result := Copy(S, start, ed - start + 1);
+	end;
+
 function Trim(const S: widestring): widestring;
 function Trim(const S: widestring): widestring;
-	var 
-	  Ofs, Len: sizeint;
 	begin
 	begin
-	  len := Length(S);
-	  while (Len>0) and (S[Len]<=' ') do
-	   dec(Len);
-	  Ofs := 1;
-	  while (Ofs<=Len) and (S[Ofs]<=' ') do
-	   Inc(Ofs);
-	  result := Copy(S, Ofs, 1 + Len - Ofs);
+	  Result := Trim(S, TTrimMode.Both);
 	end;
 	end;
 	
 	
 
 
 {   TrimLeft returns a copy of S with all blank characters on the left stripped off  }
 {   TrimLeft returns a copy of S with all blank characters on the left stripped off  }
 function TrimLeft(const S: widestring): widestring;
 function TrimLeft(const S: widestring): widestring;
-	var 
-	  i,l:sizeint;
 	begin
 	begin
-	  l := length(s);
-	  i := 1;
-	  while (i<=l) and (s[i]<=' ') do
-	   inc(i);
-	  Result := copy(s, i, l);
+	  Result := Trim(S, TTrimMode.Left);
 	end;
 	end;
 	
 	
 
 
 {   TrimRight returns a copy of S with all blank characters on the right stripped off  }
 {   TrimRight returns a copy of S with all blank characters on the right stripped off  }
 function TrimRight(const S: widestring): widestring;
 function TrimRight(const S: widestring): widestring;
-	var 
-		l:sizeint;
 	begin
 	begin
-	  l := length(s);
-	  while (l>0) and (s[l]<=' ') do
-	   dec(l);
-	  result := copy(s,1,l);
+	  Result := Trim(S, TTrimMode.Right);
 	end;
 	end;
 
 
 
 

+ 3 - 3
rtl/objpas/sysutils/syswideh.inc

@@ -12,9 +12,9 @@
     *********************************************************************
     *********************************************************************
 }
 }
 
 
-function Trim(const S: widestring): widestring;
-function TrimLeft(const S: widestring): widestring;
-function TrimRight(const S: widestring): widestring;
+function Trim(const S: widestring): widestring;{$ifdef SYSUTILSINLINE}inline;{$endif}
+function TrimLeft(const S: widestring): widestring;{$ifdef SYSUTILSINLINE}inline;{$endif}
+function TrimRight(const S: widestring): widestring;{$ifdef SYSUTILSINLINE}inline;{$endif}
 
 
 function WideUpperCase(const s : WideString) : WideString;{$ifdef SYSUTILSINLINE}inline;{$endif}
 function WideUpperCase(const s : WideString) : WideString;{$ifdef SYSUTILSINLINE}inline;{$endif}
 function WideLowerCase(const s : WideString) : WideString;{$ifdef SYSUTILSINLINE}inline;{$endif}
 function WideLowerCase(const s : WideString) : WideString;{$ifdef SYSUTILSINLINE}inline;{$endif}