Generic indicator factory
This commit is contained in:
+52
-22
@@ -18,6 +18,7 @@ type
|
||||
FTypeInfo: PtypeInfo;
|
||||
FName: string;
|
||||
FOffset: Integer;
|
||||
FSize: Integer;
|
||||
|
||||
procedure FromType(const [ref] Buffer: TBytes; const Src);
|
||||
procedure ToType(const [ref] Buffer: TBytes; var Dst);
|
||||
@@ -30,7 +31,7 @@ type
|
||||
|
||||
property Offset: Integer read FOffset;
|
||||
|
||||
constructor Create(const AName: string; AFieldType: TFieldType; ATypeInfo: PTypeInfo; AOffset: Integer);
|
||||
constructor Create(const AName: string; AFieldType: TFieldType; ATypeInfo: PTypeInfo; AOffset, ASize: Integer);
|
||||
|
||||
procedure Copy(Src, Dst: Pointer);
|
||||
|
||||
@@ -115,10 +116,6 @@ implementation
|
||||
uses
|
||||
System.Rtti;
|
||||
|
||||
const
|
||||
DataSize: array[TDataRecord.TFieldType] of Integer =
|
||||
(sizeof(Double), sizeof(Int64), sizeof(String), sizeof(TDateTime), sizeof(TDataRecord));
|
||||
|
||||
{ TDataRecord }
|
||||
|
||||
constructor TDataRecord.Create(const ALayout: TLayout; const ABuffer: TBytes);
|
||||
@@ -246,12 +243,13 @@ begin
|
||||
Dest.Layout.Fields[i].FinalizeField(Dest.FBuffer);
|
||||
end;
|
||||
|
||||
constructor TDataRecord.TField.Create(const AName: string; AFieldType: TFieldType; ATypeInfo: PTypeInfo; AOffset: Integer);
|
||||
constructor TDataRecord.TField.Create(const AName: string; AFieldType: TFieldType; ATypeInfo: PTypeInfo; AOffset, ASize: Integer);
|
||||
begin
|
||||
FName := AName;
|
||||
FFieldType := AFieldType;
|
||||
FOffset := AOffset;
|
||||
FTypeInfo := ATypeInfo;
|
||||
FSize := ASize;
|
||||
end;
|
||||
|
||||
procedure TDataRecord.TField.InitField(const [ref] Buffer: TBytes);
|
||||
@@ -289,6 +287,9 @@ begin
|
||||
end;
|
||||
|
||||
function TDataRecord.TField.GetSize: Integer;
|
||||
const
|
||||
DataSize: array[TDataRecord.TFieldType] of Integer =
|
||||
(sizeof(Double), sizeof(Int64), sizeof(String), sizeof(TDateTime), sizeof(TDataRecord));
|
||||
begin
|
||||
Result := DataSize[FFieldType];
|
||||
end;
|
||||
@@ -425,6 +426,9 @@ begin
|
||||
end;
|
||||
|
||||
class function TDataRecord.TLayout.Construct(const Def: TArray<TFieldDef>): TLayout;
|
||||
const
|
||||
DataSize: array[TDataRecord.TFieldType] of Integer =
|
||||
(sizeof(Double), sizeof(Int64), sizeof(String), sizeof(TDateTime), sizeof(TDataRecord));
|
||||
var
|
||||
Fields: TArray<TField>;
|
||||
begin
|
||||
@@ -432,7 +436,7 @@ begin
|
||||
var ofs := 0;
|
||||
for var i := 0 to High(Fields) do
|
||||
begin
|
||||
var ti: PTypeInfo;
|
||||
var ti: PTypeInfo := nil;
|
||||
case Def[i].FieldType of
|
||||
dfFloat: ti := TypeInfo(Double);
|
||||
dfInteger: ti := TypeInfo(Int64);
|
||||
@@ -441,7 +445,7 @@ begin
|
||||
dfRecord: ti := TypeInfo(TDataRecord);
|
||||
end;
|
||||
|
||||
Fields[i] := TField.Create(Def[i].Name, Def[i].FieldType, ti, ofs);
|
||||
Fields[i] := TField.Create(Def[i].Name, Def[i].FieldType, ti, ofs, DataSize[Def[i].FieldType]);
|
||||
inc(ofs, Fields[i].AlignedSize);
|
||||
end;
|
||||
|
||||
@@ -477,33 +481,59 @@ begin
|
||||
begin
|
||||
var rf := rttiFields[i];
|
||||
var ft: TFieldType := Default(TFieldType);
|
||||
var supported := true;
|
||||
var size: Integer := 0;
|
||||
|
||||
case rf.FieldType.TypeKind of
|
||||
tkInt64: ft := dfInteger;
|
||||
tkInteger:
|
||||
begin
|
||||
ft := dfInteger;
|
||||
size := sizeof(Integer);
|
||||
end;
|
||||
tkInt64:
|
||||
begin
|
||||
ft := dfInteger;
|
||||
size := sizeof(Int64);
|
||||
end;
|
||||
tkFloat:
|
||||
if rf.FieldType.HasName(GetTypeName(TypeInfo(TDateTime))) then
|
||||
ft := dfTimestamp
|
||||
else if GetTypeData(rf.FieldType.Handle).FloatType = ftDouble then
|
||||
ft := dfFloat
|
||||
begin
|
||||
ft := dfTimestamp;
|
||||
size := sizeof(TDateTime);
|
||||
end
|
||||
else
|
||||
supported := false;
|
||||
tkString, tkWString, tkLString, tkUString: ft := dfString;
|
||||
begin
|
||||
case GetTypeData(rf.FieldType.Handle).FloatType of
|
||||
ftSingle:
|
||||
begin
|
||||
ft := dfFloat;
|
||||
size := sizeof(Single);
|
||||
end;
|
||||
ftDouble:
|
||||
begin
|
||||
ft := dfFloat;
|
||||
size := sizeof(Double);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
tkString, tkWString, tkLString, tkUString:
|
||||
begin
|
||||
ft := dfString;
|
||||
size := sizeof(String);
|
||||
end;
|
||||
tkMRecord:
|
||||
begin
|
||||
if rf.FieldType.HasName(GetTypeName(TypeInfo(TDataRecord))) then
|
||||
ft := dfRecord
|
||||
else
|
||||
supported := false;
|
||||
begin
|
||||
ft := dfRecord;
|
||||
size := sizeof(TDataRecord);
|
||||
end
|
||||
end;
|
||||
else
|
||||
supported := false;
|
||||
end;
|
||||
|
||||
if not supported then
|
||||
if size = 0 then
|
||||
raise Exception.Create('Type ' + rf.FieldType.Name + ' not supported in data records');
|
||||
|
||||
fields[i] := TField.Create(rf.Name, ft, rf.FieldType.Handle, rf.Offset);
|
||||
fields[i] := TField.Create(rf.Name, ft, rf.FieldType.Handle, rf.Offset, size);
|
||||
end;
|
||||
|
||||
Result.Create(fields);
|
||||
|
||||
Reference in New Issue
Block a user