unit daten;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, Menus, StdCtrls, Contnrs;
// Basisklassen
type
TBaseObject =
class (TPersistent)
protected
procedure LoadFromStream(Reader:TReader);
virtual;
abstract;
procedure SaveToStream(Writer:TWriter);
virtual;
abstract;
end;
//Referenztyp zur Klassifiezirung der Daten
type
TObjectClassRef =
Class of TBaseObject;
//Hier werden die unterschiedlichen Typen des BaseObjects deklariert
//Die Namen der TBaseObject-Ableitungen MÜSSEN einzigartig sein!
TName =
class(TBaseObject)
private
fID : Integer;
fName :
String;
FHerkunft :
String;
fGeschlecht : Boolean;
protected
procedure LoadFromStream(Reader:TReader);
override;
procedure SaveToStream(Writer:TWriter);
override;
public
property ID : Integer
Read fID
Write fID;
property Name :
String Read fName
Write fName;
property Herkunft :
String Read fHerkunft
Write fHerkunft;
property Geschlecht : Boolean
Read fGeschlecht
Write fGeschlecht;
end;
//Und natürlich das wichtigste. Die Objectliste, mit der gearbeitet wird.
//Hiervon können natürlich weitere Objecte abgeleitet werden.
type
TMyObjectList =
class(TObjectList)
private
protected
function GetItem(
Index:Integer):TBaseObject;
procedure RegisterObjects;
public
constructor Create;
function Add(AObject:TBaseObject):Integer;
procedure LoadFromStream(Stream:TStream);
procedure SaveToStream(Stream:TStream);
procedure LoadFromFile(FileName:
String);
procedure SaveToFile(FileName:
String);
property Items[
Index:Integer]:TBaseObject
read GetItem;
end;
implementation
procedure TName.LoadFromStream(Reader:TReader);
begin
//Hier werden die Daten aus den Reader gelesen
fID := Reader.ReadInteger;
fName := Reader.ReadString;
fHerkunft := Reader.ReadString;
fGeschlecht := Reader.ReadBoolean;
end;
procedure TName.SaveToStream(Writer:TWriter);
begin
//Hier werden die Daten in den Writer geschrieben
Writer.WriteInteger(fID);
Writer.WriteString(fName);
Writer.WriteString(fHerkunft);
Writer.WriteBoolean(fGeschlecht);
end;
{ Nicht zugeordnete Methoden }
procedure WriteClassRef(Writer: TWriter; o: TObject);
begin
// Bestimmen und Schreiben des Klassennamens
Writer.WriteString(o.ClassName);
end;
function ReadClassRef(R: TReader): TClass;
var
ClassName:
String;
begin
//Auslesen des KlassenNamens
ClassName := R.ReadString;
//Rückgabe des Klassennamens
Result := FindClass(ClassName);
end;
{ Methoden der Basisklasse Objectliste }
constructor TMyObjectList.Create;
begin
//Aufrufen der ererbten Methode Create
inherited Create(true);
end;
procedure TMyObjectList.RegisterObjects;
begin
//Registrierung der TBaseObject-Ableitungen
RegisterClass(TName);
end;
function TMyObjectList.Add(AObject:TBaseObject):Integer;
begin
//Hinzufügen eines TBaseObjectes zur Objectliste
result:=inherited Add(AObject);
end;
function TMyObjectList.GetItem(
Index:Integer):TBaseObject;
begin
//Rückgabe eines TBaseObjectes durch die ererbte Methode Items[index]
result:=TBaseObject(
inherited Items[
Index]);
end;
procedure TMyObjectList.LoadFromStream(Stream:TStream);
var
i : Integer;
NewObjectRef : TObjectClassRef;
Reader : TReader;
NewObject : TBaseObject;
begin
//Aufruf der nachträglichen Registrierung der TBaseObject
RegisterObjects;
//Erstellen eines Readers
Reader := TReader.Create(Stream, 1024);
//Löschen des aktuellen Inhalts der aktuellen ObjectList
Clear;
//Auslesen der Menge der abgespeicherten Objecte
count := Reader.ReadInteger;
for i:=0
to count-1
do begin
//Auslesen des Typs der TBaseObject-Ableitung
NewObjectRef := TObjectClassRef(ReadClassRef(Reader));
//Erstellen eines neuen Instanz dieser Ableitung
NewObject := NewObjectRef.Create;
//Auslesen der gespeicherten Informationen
NewObject.LoadFromStream(Reader);
//Einfügen an ausgeleser Position in der Objectliste
Insert (i, NewObject);
end;
//Freigabe des Readers
Reader.Free;
end;
procedure TMyObjectList.SaveToStream(Stream:TStream);
var
i,c : Integer;
Writer : TWriter;
begin
// Erstellen eines TWriters
writer := TWriter.Create(Stream, 1024);
// Abfrage, wie viele Objecte die Objectliste enthält
c:=Count;
// Schreiben der Objectanzahl
Writer.WriteInteger(C);
for i:=0
to c-1
do begin
// Schreiben des TBaseObjects-Typen-Namen
WriteClassRef(Writer, Items[i]);
// Speichern der gewünschten Informationen
Items[i].SaveToStream(Writer);
end;
// Freigabe des Writers
Writer.Free;
end;
procedure TMyObjectList.LoadFromFile(FileName:
String);
var
Stream : TFileStream;
begin
// Öffnen der Datei
Stream := TFileStream.Create(FileName, fmOpenRead);
// Aufruf von LoadfromStream, da alle notwendigen Funktionen hier schon
// definiert wurden
LoadFromStream(Stream);
// Freigabe des Streams
Stream.Free;
end;
procedure TMyObjectList.SaveToFile(FileName:
String);
var
Stream : TFileStream;
begin
// Erzeugen einer leeren Datei
Stream:= TFileStream.Create(FileName, fmCreate);
// Aufruf von SaveToStream, da alle notwendigen Funktionen hier schon
// definiert wurden
SaveToStream(Stream);
// Freigabe des Streams
Stream.Free;
end;
end.