unit GenData;

{ Resource Support for Generic Data, Copr. 1994 Matthias K”ppe
}

interface

uses Objects;

type
  PGenericData = ^TGenericData;
  TGenericData = object(TObject)
    Size: LongInt;
    Data: record end;
    function Load(var S: TStream; VMT: Word): pointer;
    function DoDone(VMT: Word): pointer;
    destructor Done; virtual;
  end;

  PGenericDataMaker = ^TGenericDataMaker;
  TGenericDataMaker = object(TObject)
    Data: pointer;
    Size: LongInt;
    constructor Init(AData: pointer; ASize: LongInt);
    procedure Store(var S: TStream);
  end;

const
  RGenericData: TStreamRec = (
    ObjType: 999;
    VmtLink: Ofs(TypeOf(TGenericData)^);
    Load:    @TGenericData.Load;
    Store:   nil);

  RGenericDataMaker: TStreamRec = (
    ObjType: 999;
    VmtLink: Ofs(TypeOf(TGenericDataMaker)^);
    Load:    nil;
    Store:   @TGenericDataMaker.Store);

implementation

function TGenericData.Load(var S: TStream; VMT: Word): pointer;
var
  asize: LongInt;
  p: PGenericData;
Begin
  If @Self = nil then Begin
    S.Read(asize, 4);
    GetMem(p, size + SizeOf(TGenericData));
    Move(VMT, p^, 2);
    p^.size := asize;
    S.Read(p^.Data, asize);
    Load := p
  End
End;

function TGenericData.DoDone(VMT: Word): pointer;
Begin
  If VMT <> 0 then
  FreeMem(@Self, Size + SizeOf(TGenericData));
End;

destructor TGenericData.Done; assembler;
asm
	leave
	jmp	TGenericData.DoDone
	{ Skip destructor code... }
end;

{ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ }

constructor TGenericDataMaker.Init(AData: pointer; ASize: LongInt);
Begin
  TObject.Init;
  Data := AData;
  Size := ASize
End;

procedure TGenericDataMaker.Store(var S: TStream);
Begin
  S.Write(Size, 4);
  S.Write(Data^, Size)
End;

end.
