Pārlūkot izejas kodu

* SafeFormat and helper function to convert array of const to string in a safe manner

(cherry picked from commit 6ff542a13eb30a608b38e36679216b8e621fa6c9)
Michael Van Canneyt 2 gadi atpakaļ
vecāks
revīzija
80ace756b5

+ 17 - 0
rtl/objpas/sysutils/sysstr.inc

@@ -1152,6 +1152,23 @@ begin
   Result:=Format(Fmt,Args,DefaultFormatSettings);
   Result:=Format(Fmt,Args,DefaultFormatSettings);
 end;
 end;
 
 
+function SafeFormat (const Fmt: AnsiString; Args: array of const): UTF8String;
+
+begin
+  Result:=SafeFormat(Fmt,Args,DefaultFormatSettings);
+end;
+
+function SafeFormat (const Fmt: AnsiString; Args: array of const; const FormatSettings: TFormatSettings): UTF8String;
+
+begin
+  try
+    Result:=Format(Fmt,Args,FormatSettings);
+  except
+    On E : Exception do
+      Result:='Error "'+E.ClassName+'" during format('''+Fmt+''',['+ArrayOfConstToStr(Args,',','{','}')+']) : '+E.Message;
+  end;
+end;
+
 Function FormatBuf (Var Buffer; BufLen : Cardinal; Const Fmt; fmtLen : Cardinal; Const Args : Array of const; Const FormatSettings: TFormatSettings) : Cardinal;
 Function FormatBuf (Var Buffer; BufLen : Cardinal; Const Fmt; fmtLen : Cardinal; Const Args : Array of const; Const FormatSettings: TFormatSettings) : Cardinal;
 
 
 Var S,F : String;
 Var S,F : String;

+ 2 - 0
rtl/objpas/sysutils/sysstrh.inc

@@ -338,3 +338,5 @@ Type
 Type
 Type
   TStringBuilder = TAnsiStringBuilder;
   TStringBuilder = TAnsiStringBuilder;
 
 
+function SafeFormat (const Fmt: AnsiString; Args: array of const; const FormatSettings: TFormatSettings): UTF8String; overload;
+function SafeFormat (const Fmt: AnsiString; Args: array of const): UTF8String; overload;

+ 6 - 0
rtl/objpas/sysutils/sysutilh.inc

@@ -365,3 +365,9 @@ const
   ufImplicitUnit = $10;
   ufImplicitUnit = $10;
 
 
   ufWeakPackageUnit = ufPackageUnit or ufWeakUnit;
   ufWeakPackageUnit = ufPackageUnit or ufWeakUnit;
+
+Type
+  TUTF8StringDynArray = Array of UTF8String;
+
+Function ArrayOfConstToStr(Args: array of const ; aSeparator : Char = ','; aQuoteBegin : Char = '"'; aQuoteEnd : Char = '"') : UTF8String;
+Function ArrayOfConstToStrArray(Args: array of const) : TUTF8StringDynArray;

+ 88 - 0
rtl/objpas/sysutils/sysutils.inc

@@ -837,3 +837,91 @@ begin
     Result:=ifFalse;
     Result:=ifFalse;
 end;
 end;
 {$ENDIF}
 {$ENDIF}
+
+Function ArrayOfConstToStrArray(Args: array of const) : TUTF8StringDynArray;
+
+var
+  i: Integer;
+  O : TObject;
+  C : TClass;
+  S : String;
+
+begin
+  SetLength(Result,Length(Args));
+  for i:=Low(Args) to High(Args) do
+    case Args[i].VType of
+      vtInteger:      Result[i]:=IntToStr(Args[i].VInteger);
+      vtBoolean:      Result[i]:=BoolToStr(Args[i].VBoolean);
+      vtChar:         Result[i] := Args[i].VChar;
+      {$ifndef FPUNONE}
+      vtExtended:     Result[i]:= FloatToStr(Args[i].VExtended^);
+      {$ENDIF}
+      vtString:       Result[i] := Args[i].VString^;
+      vtPointer:      Result[i] := '0x'+HexStr(PtrInt(Args[i].VPointer),SizeOF(PtrInt));
+      vtPChar:        Result[i] := Args[i].VPChar;
+      vtObject:
+        begin
+        O:=Args[i].VObject;
+        if Assigned(O) then
+          begin
+          try
+            S:=O.ClassName;
+          except
+            S:='<Invalid instance>';
+          end;
+          end
+        else
+          S:='';
+        Result[I] := '<Object '+S+' 0x'+HexStr(PtrInt(O),SizeOF(PtrInt))+'>';
+        end;
+      vtClass:
+        begin
+        C:=Args[i].VClass;
+        if Assigned(C) then
+          begin
+          try
+            S:=C.ClassName;
+          except
+            S:='<Invalid Class>';
+          end;
+          end
+        else
+          S:='';
+        Result[I] := '<Class '+S+' 0x'+HexStr(PtrInt(C),SizeOF(PtrInt))+'>';
+        end;
+      vtWideChar:     Result[i] := UTF8Encode(Args[i].VWideChar);
+      vtPWideChar:    Result[i] := UTF8Encode(Args[i].VPWideChar^);
+      vtAnsiString:   Result[i] := AnsiString(Args[i].VAnsiString);
+      vtCurrency:     Result[i] := FLoatToSTr(Args[i].VCurrency^);
+      vtVariant:      Result[i] := Args[i].VVariant^;
+      vtInterface:    Result[I] := '<Interface 0x'+HexStr(PtrInt(Args[i].VInterface),SizeOF(PtrInt))+'>';
+      vtWidestring:   Result[i] := UTF8ENcode(WideString(Args[i].VWideString));
+      vtInt64:        Result[i] := IntToStr(Args[i].VInt64^);
+      vtQWord:        Result[i] := IntToStr(Args[i].VQWord^);
+      vtUnicodeString:Result[i] := UTF8Encode(UnicodeString(Args[i].VUnicodeString));
+    end;
+end;
+
+Function ArrayOfConstToStr(Args: array of const ; aSeparator : Char = ','; aQuoteBegin : Char = '"'; aQuoteEnd : Char = '"') : UTF8String;
+
+  Procedure Add(s: UTF8String);
+
+  begin
+    if aQuoteBegin<>#0 then
+      S:=aQuoteBegin+S;
+    if aQuoteEnd<>#0 then
+      S:=S+aQuoteEnd;
+    if Result<>'' then
+      Result:=Result+aSeparator;
+    Result:=Result+S;
+  end;
+
+
+Var
+  S : UTF8String;
+
+begin
+  Result:='';
+  For S in ArrayOfConstToStrArray(Args) do
+    Add(S);
+end;