Verwende
OOP.
Finde die Gemeinsamkeiten der einzelnen Blöcke (wenn es welche gibt)
Erstelle eine Basisklasse.
Delphi-Quellcode:
Type
TAbstractTAGClass = Class
public
Procedure Read (Data : TStreamData); Virtual; Abstract;
Class Function TAG : Integer; Virtual; Abstract;
End;
Leite alle TAG-Klassen (also Klassen, die genau einen Blocktyp verarbeiten) von der Basisklasse ab.
Delphi-Quellcode:
Type
TMyTagClass = Class (TAbstractTAGClass)
public
Procedure Read (Data : TStreamData); Override;
Class Function TAG : Integer; Override;
End;
Procedure TMyTagClass.Read(Data : TStreamData);
Begin
// Diese Klasse liest ein Byte und einen Integer-Wert
fMyByte := Data.ReadByte;
fMyInteger := Data.ReadInteger;
...
End;
Class Function TMyTagClass.TAG : Integer;
Begin
// diese Klasse wird durch den TAG '1' im Byte-Array gekennzeichnet
Result := 1;
End;
Jede TAG-Klasse liest genau einen Blocktyp ein und stellt den Inhalt als Eigenschaften zur Verfügung.
Erstelle eine Classfactory, die die entsprechende Klasse anhand des gelesenen TAGs liefert.
Diese ClassFactory ist eine sehr einfache Klasse. Sie verwaltet eine Liste von Tag/Klassen-Paaren.
Delphi-Quellcode:
Type
TClassFactory = Class
fClasses : TClassList;
Public
Constructor Create;
Procedure RegisterTagClass (aTagClass : TAbstractTAGClass);
Function GetClassByTag (aTag : Integer) : TAbstractTAGClass;
End;
...
Function TClassFactory.RegisterClass (aTagClass : TAbstractTAGClass);
Begin
fClasses.Add(aTagClass)
End;
Function TClassFactory.GetClassByTag (aTag : Integer) : TAbstractTAGClass;
Begin
For Result in fClasses do
if Result.TAG = aTAG Then
Exit;
Result := nil
End;
Alle deine TAG-Klassen registrieren sich bei dieser Classfactory.
Delphi-Quellcode:
...
ClassFactory.RegisterClass(TMyTAGClass);
ClassFactory.RegisterClass(TMyOtherTAGClass);
...
Immer wenn ein neuer TAG-Typ eingeführt wird, leitest du eine entsprechende Klasse von TAbstractTAGClass ab und registrierst diese Klasse in der ClassFactory.
Schau mal, wie simpel die Leseroutine ist. Du wirst sie nie wieder anfassen müssen:
Delphi-Quellcode:
...
While not Data.EndReached Do Begin
Tag := Data.ReadTag;
DataObject := ClassFactory.GetClassByTag(Tag).Create;
DataObject.Read(Data);
// Was immer du mit den Daten anstellen willst, tu es hier
// Du kannst die Objekte in eine Liste packen, dann hättest du deine Daten interpretiert
// Oder du implementierst in den Klassen eine eigene 'Execute'-Methode. Die rufst Du hier auf
//
// DataObject.Execute;
//
// Vielleicht wieder freigeben.
End;
Der Kernpunkt ist diese Klassenfabrik, die dir für den TAG-Header die richtige Klasse zum Lesen der folgenden Daten liefert.
So. Das ist skalierbar bis zum geht-nicht-mehr. Du wirst Dir eventuell die 'GetClassByTag'-Methode vorknöpfen müssen, wenn du zu viele Klassen hast und Performance eine große Rolle spielt: Das Suchen der Klasse mit dem richtigen Tag ist ja nur beispielhaft implementiert (Stichwort: Sortierte Liste, Hashmap o.ä).