Die Anwendungs-Datenstruktur enthält oft redundante Daten, die nicht unbedingt in einer Datei gespeichert werden müssen, sondern zur Laufzeit aus den gespeicherten Daten berechnet werden können. Zudem will man vielleicht Daten verschlüsselt oder sonst wie codiert in der Datei speichern. Daher ist die zu erzeugende Seq-Struktur nicht unbedingt eine 1:1 Abbildung der Anwendungs-Datenstruktur.
Unter OOP-Richtlinien programmiert man so, dass jedes Anwendungs-Objekt Funktionen bekommt, die sich selbst Serialisieren und Parsen können.
Unsere Anwendung soll eine Liste von Benutzern mit Benutzername, Passwort und Benutzertyp verwalten und ein paar globale Einstellungen speichern können. Die entsprechenden Objekte der Anwendung seien folgendermassen definiert:
class CAppli public Globals ' as CGlobals public UserList ' as CUserList : end class class CGlobals public Language ' as string public LastDate ' as date : end class class CUserList public Users ' as array of CUser : end class class CUser public Name ' as string public Pwd ' as string public IsAdmin ' as boolean : end class
Jede Klasse erhält nun je eine Funktion Serialize, welche aus dem Objekt einen Seq-String erzeugt, und eine Funktion Parse mit der umgekehrten Funktionalität.
Diese Funktionen sind für die Klassen CGlobals und CUser sehr einfach zu implementieren:
class CGlobals
:
sub Serialize( aSerializer )
aSerializer.OpenSubData 3
aSerializer.AddNL
aSerializer.AddStr Language
aSerializer.AddDate LastDate
aSerializer.CloseSubData
end sub
sub Parse( aParser )
aParser.OpenSubData
Language = aParser.GetStrD( "de" )
LastDate = aParser.GetDateD( Now )
aParser.CloseSubData
end sub
:
end class
class CUser
:
sub Serialize( aSerializer )
aSerializer.OpenSubData 4
aSerializer.AddNL
aSerializer.AddStr Name
aSerializer.AddStr Pwd
aSerializer.AddBool IsAdmin
aSerializer.CloseSubData
end sub
sub Parse( aParser )
aParser.OpenSubData
Name = aParser.GetStr()
Pwd = aParser.GetStr()
IsAdmin = aParser.GetBool()
aParser.CloseSubData
end sub
:
end class
Beachte, dass die Properties der Objekte in der gleichen Reihenfolge gelesen werden (GetXxx) wie sie serialisiert wurden (AddXxx)!
Die Funktion AddNL kann zum Formatieren des Seq-String verwendet werden. Sie fügt einen Zeilenumbruch ein, der beim Lesen ignoriert wird, aber das Lesen eines Seq-Files für Menschen erleichtert.
Für die User-Liste sieht Serialize folgendermassen aus:
class CUserList
:
sub Serialize( aSerializer )
dim sz, i
sz = UBound(UserList) + 1
aSerializer.OpenSubData 2 + sz
aSerializer.AddNL
aSerializer.AddNum sz
for i = 0 to UBound(UserList)
UserList(i).Serialize( aSerializer )
next
aSerializer.CloseSubData
end sub
sub Parse( aParser )
dim last, user, i
UserList = Array()
aParser.OpenSubData
last = aParser.GetNum() - 1
if last < 0 then
aParser.CloseSubData
exit sub
end if
redim UserList( last )
for i = 0 to last
set user = new CUser
user.Parse aParser
set UserList(i) = user
next
aParser.CloseSubData
end sub
:
end class
Jetzt fehlen nur noch die Funktionen auf Appli-Ebene:
class CAppli
:
sub Serialize( aSerializer )
aSerializer.OpenSubData 4
aSerializer.AddNL
aSerializer.AddStr "CAppli"
Globals.Serialize aSerializer
UserList.Serialize aSerializer
aSerializer.CloseSubData
end sub
function Parse( aParser )
aParser.OpenSubData
if aParser.GetStr() <> "CAppli" then
aParser.CloseSubData
Parse = false
exit function
end if
Globals.Parse aParser
UserList.Parse aParser
aParser.CloseSubData
Parse = true
end function
:
end class
Der String "CAppli" wird als ID für diese Anwendung gespeichert. Beim Parsen wird der Seq-String überprüft, ob er "CAppli" enthält. Nur dann werden die weiteren Daten eingelesen.
Jetzt fehlen nur noch die Funktionen CAppli.SaveToFile und CAppli.LoadFromFile:
class CAppli
:
sub SaveToFile( aFilename )
dim serializer, seqString
set serializer = NewSerializer(1)
Serialize serializer
seqString = serializer.GetString(false)
FS.WriteFile aFilename, seqString
end sub
function LoadFromFile( aFilename )
dim seqString, parser
LoadFromFile = false
seqString = FS.ReadFile( aFilename )
if seqString = "" then exit function
set parser = NewParser( seqString )
LoadFromFile = Parse( parser )
end function
:
end class
Damit können die Appli-Daten sehr einfach in eine Datei gespeichert und wieder geladen werden:
dim Appli set Appli = new CAppli Appli.LoadFromFile "applidata.txt" : Appli.SaveToFile "applidata.txt"
Eine solche Datei applidata.txt könnte folgendermassen aussehen:
72| 6|CAppli|22| 2|de|31.12.2009 23:59|| 38| 2|19| 5|Admin|4|****|1||18| 4|Gast|4|****|0||||