views:

146

answers:

1

I try to write a kind of object/record serializer with Delphi 2010 and wonder if there is a way to detect, if a record is a variant record. E.g. the TRect record as defined in Types.pas:

TRect = record
case Integer of
  0: (Left, Top, Right, Bottom: Longint);
  1: (TopLeft, BottomRight: TPoint);
end; 

As my serializer should work recursively on my data structures, it will descent on the TPoint records and generate redundant information in my serialized file. Is there a way to avoid this, by getting detailed information on the record?

+1  A: 

One solution could be as follows:

procedure SerializeRecord (RttiRecord : TRttiRecord)

var
  AField : TRttiField;
  Offset : Integer;

begin
Offset := 0;
for AField in RttiRecord.Fields do
  begin
  if AField.Offset < Offset then Exit;
  Offset := AField.Offset; //store last offset
  SerializeField (AField);
  end;
end;

But this solution is not a proper solution for all cases. It only works for serialization, if the different variants contain the same information and the same types. If you have something like the following (from wikipedia.org):

type   
  TVarRec = packed record
  case Byte of
    0: (FByte: Byte;
        FDouble: Double);
    1: (FStr: ShortString);
  end;

Would you serialize

FByte=6
FDouble=1.81630607010916E-0310

or would it be better to serialize

FStr=Hello!

Yes, for sure, this would also be the same for a computer but not for a file which should be readable or even editable for humans.

So I think, the only way to solve the problem is using an Attribute, to define, which variant should be used for serialization.

Christian Metzler
By the way: The sizes of variant parts of a record can be different! With the current solution it might be possible to lose information. So there should be a check it the accumulated field sizes fit the record's size.
Christian Metzler