|
Registriert seit: 24. Feb 2007 Ort: Baden 1.566 Beiträge Delphi 2007 Professional |
#1
Hallo,
ich benötige eine Typ-Konvertierung in alle Richtungen. Dabei soll jede Umwandlung ein Ergebnis liefern, also z.B. auch Boolean nach TDateTime (Hier gibt True Now zurück). Die Daten liegen in einem SpeicherPuffer, stehen als Quelle somit als Cast(Pointer) bereit. Bei der Rückgabe benötige ich einmal einen Weg, wieder in den Puffer zu schreiben (Puffergröße ist immer ausreichend), als auch eine Funktions-Rückgabe mit korrektem Daten-Typ (allerdings ohne Bereichs-Prüfung, Byte := LongInt reicht also). Ich hab' es inzwischen gelöst, aber je öfter ich mir den Code anschaue, desto mehr denke ich, das ist umständlich ![]() Kann man das auch eleganter lösen? Hier mal mein Werk (wenn es zu lang ist, klemme ich es als Anlage an, einfach was sagen):
Delphi-Quellcode:
PS: st_Chars ist entweder @String[1] oder ein PChar
unit stTypChange;
interface uses SysUtils, stConst, stTypes; procedure ConvertPtr(SourcePtr, TargetPtr : Pointer; SourceTyp, TargetTyp : TstDataTyp; TargetSize: Integer); function Pointer2String (aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): AnsiString; function Pointer2Boolean (aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): Boolean; function Pointer2Integer (aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): Int64; function Pointer2Float (aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): Double; function Pointer2Currency (aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): Currency; function Pointer2DateTime (aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): TDateTime; function DateTimeToStrDef(DateTime: TDateTime; Default: String) : String; function StrToDateTimeDef(Text : String; Default : TDateTime): TDateTime; function StrToFloatDef(Text : String; Default : Double): Double; function StrToCurrDef(Text : String; Default : Currency) : Currency; implementation procedure ConvertPtr(SourcePtr, TargetPtr : Pointer; SourceTyp, TargetTyp : TstDataTyp; TargetSize: Integer); begin case TargetTyp of st_Boolean : Boolean(TargetPtr^) := Pointer2Boolean (SourcePtr, SourceTyp, TargetSize); st_Byte : Byte(TargetPtr^) := Pointer2Integer (SourcePtr, SourceTyp, TargetSize); st_Word : Word(TargetPtr^) := Pointer2Integer (SourcePtr, SourceTyp, TargetSize); st_SmallInt : SmallInt(TargetPtr^) := Pointer2Integer (SourcePtr, SourceTyp, TargetSize); st_Integer : LongInt(TargetPtr^) := Pointer2Integer (SourcePtr, SourceTyp, TargetSize); st_LargeInt : Int64(TargetPtr^) := Pointer2Integer (SourcePtr, SourceTyp, TargetSize); st_Real48 : Real48(TargetPtr^) := Pointer2Float (SourcePtr, SourceTyp, TargetSize); st_Double : Double(TargetPtr^) := Pointer2Float (SourcePtr, SourceTyp, TargetSize); st_DateTime : TDateTime(TargetPtr^):= Pointer2DateTime(SourcePtr, SourceTyp, TargetSize); st_Currency : Currency(TargetPtr^) := Pointer2Currency(SourcePtr, SourceTyp, TargetSize); st_Chars : StrCopy(PChar(TargetPtr), PChar(SourcePtr)); st_ShortStr : ShortString(TargetPtr^) := PChar(SourcePtr); end; end; {<--- TO STRING --->} function Pointer2String(aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): AnsiString; begin case AsTyp of st_Boolean : if Boolean(aPtr^) then Result := BoolTrueString else Result := BoolFalseString; st_Byte : Result := IntToStr(Byte(aPtr^)); st_Word : Result := IntToStr(Word(aPtr^)); st_SmallInt : Result := IntToStr(SmallInt(aPtr^)); st_Integer : Result := IntToStr(Integer(aPtr^)); st_LargeInt : Result := IntToStr(Int64(aPtr^)); st_Real48 : Result := FloatToStrF(Real48(aPtr^), ffFixed, 15, Size); st_Double : Result := FloatToStrF(Double(aPtr^), ffFixed, 15, Size); st_DateTime : Result := DateTimeToStrDef(TDateTime(aPtr^),''); st_Currency : Result := Format('%m',[Currency(aPtr^)]); st_Chars : Result := PChar(aPtr); st_ShortStr : Result := ShortString(aPtr^); end; end; {<--- TO BOOLEAN --->} function Pointer2Boolean(aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): Boolean; begin case AsTyp of st_Boolean : Result := Boolean(aPtr^); st_Byte : Result := Byte(aPtr^) <> 0; st_Word : Result := Word(aPtr^) <> 0; st_SmallInt : Result := SmallInt(aPtr^) <> 0; st_Integer : Result := Integer(aPtr^) <> 0; st_LargeInt : Result := Int64(aPtr^) <> 0; st_Real48 : Result := Real48(aPtr^) <> 0; st_Double : Result := Double(aPtr^) <> 0; st_DateTime : Result := Double(aPtr^) <> 0; st_Currency : Result := Currency(aPtr^) <> 0; st_Chars : Result := UpperCase(PChar(aPtr)) = UpperCase(BoolTrueString); st_ShortStr : Result := UpperCase(ShortString(aPtr^)) = UpperCase(BoolTrueString); else Result := False; end; end; {<--- TO INTEGER --->} function Pointer2Integer(aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): Int64; begin case AsTyp of st_Boolean : if Boolean(aPtr^) then Result := 1 else Result := 0; st_Byte : Result := Byte(aPtr^); st_Word : Result := Word(aPtr^); st_SmallInt : Result := SmallInt(aPtr^); st_Integer : Result := Integer(aPtr^); st_LargeInt : Result := Int64(aPtr^); st_Real48 : Result := Trunc(Real48(aPtr^)); st_Double : Result := Trunc(Double(aPtr^)); st_DateTime : Result := Trunc(Double(aPtr^)); st_Currency : Result := Trunc(Currency(aPtr^)); st_Chars : Result := StrToInt64Def(PChar(aPtr), 0); st_ShortStr : Result := StrToInt64Def(ShortString(aPtr^),0); else Result := 0; end; end; {<--- TO FLOAT --->} function Pointer2Float(aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): Double; begin case AsTyp of st_Boolean : if Boolean(aPtr^) then Result := 1 else Result := 0; st_Byte : Result := Byte(aPtr^); st_Word : Result := Word(aPtr^); st_SmallInt : Result := SmallInt(aPtr^); st_Integer : Result := Integer(aPtr^); st_LargeInt : Result := Int64(aPtr^); st_Real48 : Result := Real48(aPtr^); st_Double : Result := Double(aPtr^); st_DateTime : Result := Double(aPtr^); st_Currency : Result := Currency(aPtr^); st_Chars : Result := StrToFloatDef(PChar(aPtr),0); st_ShortStr : Result := StrToFloatDef(ShortString(aPtr^),0); else Result := 0; end; end; {<--- TO CURRENCY --->} function Pointer2Currency(aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): Currency; begin case AsTyp of st_Boolean : if Boolean(aPtr^) then Result := 1 else Result := 0; st_Byte : Result := Byte(aPtr^); st_Word : Result := Word(aPtr^); st_SmallInt : Result := SmallInt(aPtr^); st_Integer : Result := Integer(aPtr^); st_LargeInt : Result := Int64(aPtr^); st_Real48 : Result := Real48(aPtr^); st_Double : Result := Double(aPtr^); st_DateTime : Result := Double(aPtr^); st_Currency : Result := Currency(aPtr^); st_Chars : Result := StrToCurrDef(PChar(aPtr), 0); st_ShortStr : Result := StrToCurrDef(ShortString(aPtr^), 0); else Result := 0; end; end; {<--- TO DATETIME --->} function Pointer2DateTime (aPtr : Pointer; AsTyp : TstDataTyp; Size : Integer): TDateTime; begin case AsTyp of st_Boolean : if Boolean(aPtr^) then Result := Now else Result := 0; st_Byte : Result := Byte(aPtr^); st_Word : Result := Word(aPtr^); st_SmallInt : Result := SmallInt(aPtr^); st_Integer : Result := Integer(aPtr^); st_LargeInt : Result := Int64(aPtr^); st_Real48 : Result := Real48(aPtr^); st_Double : Result := Double(aPtr^); st_DateTime : Result := Double(aPtr^); st_Currency : Result := Currency(aPtr^); st_Chars : Result := StrToDateTimeDef(PChar(aPtr), 0); st_ShortStr : Result := StrToDateTimeDef(ShortString(aPtr^), 0); else Result := 0; end; end; {******************************************************** StringUmwandlung mit Exception-Behandlung und Default ********************************************************} {<--- DateTime > String --->} function DateTimeToStrDef(DateTime: TDateTime; Default: String) : String; begin try Result := DateTimeToStr(DateTime) except on EInvalidOp do Result := Default; end; end; {<--- String > DateTime --->} function StrToDateTimeDef(Text : String; Default : TDateTime): TDateTime; begin try Result := StrToDateTime(Text) except on EConvertError do Result := default; end; end; {<--- String > Float --->} function StrToFloatDef(Text : String; Default : Double): Double; begin try Result := StrToFloat(Text) except on EConvertError do Result := Default; end; end; {<--- String > Currency --->} function CleanCurrStr(Str : String): String; var i : Integer; begin Result := Str; for i := Length(Result) downto 1 do if Pos(Result[i],'+-0123456789'+DecimalSeparator) < 1 then Delete(Result, i,1); (* Result := ''; for i := 1 to Length(Str) do if Pos(Str[i],'+-0123456789'+DecimalSeparator) > 0 then Result := Result + Str[i]; *) end; function StrToCurrDef(Text : String; Default : Currency) : Currency; begin try Result := StrToCurr(CleanCurrStr(Text)) except on EConvertError do Result := default; end; end; end. PPS: TargetSize ist z.Z. noch irreführend. Größe muss nicht (mehr) beschränkt werden. Dient z.Z. noch als optionale Angabe, z.B. für Nachkommastellen. |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |