Das Speichern im Quellentext als Datensprache wurde in dem entwickelten Prototyp in der Tcl-Syntax realisiert. Zum Speichern wird vom Canvas Element (engl.: ,,canvas widget``) der aktuelle Inhalt an Objekten abgefragt und dann eine Beschreibung der Objekte in einer Datei abgelegt.
Die Beschreibung könnte bezüglich Form und Formatierung auf viele individuelle und proprietäre Arten vorgenommen werden. Die konventionellen Formate sind aber in der Regel meist nicht nur proprietär sondern auch nicht intuitiv. So ist nicht immer ohne weiteres erkennbar, welcher Teil einer Beschreibung eines Objektes mit welcher Eigenschaft in Beziehung steht.
Beispiele für konventionelle Daten wurden bereits in Abschnitt 1.3 unter Punktdaten, Liniendaten und Polygondaten exemplarisch dargestellt.
Es ist deutlich ersichtlich, daß Funktionen zum Laden solcher Daten nicht intuitiv sein können.
Ein Datensatz auf Basis von Quellentext kann im einfachsten Fall
hingegen mit einem source
Befehl oder mit
einer Funktion geladen werden, wie sie in
Abbildung 9.5 dargestellt ist.
proc myopenSource {FileName} { global w source $FileName } |
Abbildung 9.5: Anwendungsbeispiel: Benutzerdefinierte Funktion zum Laden von Quellentext-Daten in einer Komponente
Für bestimmte Funktionalitäten, z.B. Handhabung
global vereinbarter Definitionen oder der temporären Speicherung
der Namen geladener Datensätze, können zusätzliche
einfache Mittel in einer solchen Funktion zur Verfügung
gestellt werden. Globale Variablen, wie hier $w
bzw. w
können deklariert werden, wenn die geladenen
Datensätze globale Variablen enthalten, z.B. für die Angabe
eines Canvas, die nicht als Funktionsargument
übergeben werden.
Verschiedene Funktionen können für verschiedene Aufgaben
parallel bereitgestellt
und bei Bedarf auch dynamisch
nachgeladen oder ausgewechselt werden. In diesem Beispiel
beginnen die Funktionsnamen mit my
damit keine
bereits vorhandenen, systemeigenen Funktionsnamen umdefiniert werden.
Eine Variante dieser Funktion, zur Nutzung eines sicheren Interpreters, kann ebenso einfach erzeugt werden (Abbildung 9.6).
proc mysopenSource {FileName} { if { [catch { mySafeOpenSource $FileName } tmpcatch ] } { puts "WARNING: $tmpcatch" puts "DIAGNOSTICS: We have NOT\ executed some commands\ as these might be unsafe." puts "TIP: You might\ inspect $FileName\ for further action." } else { } } |
Abbildung 9.6: Anwendungsbeispiel: Benutzerdefinierte Funktion zum Laden von Quellentext-Daten über sicheren Interpreter in einer Komponente
Es wird der Name eines Datensatzes übergeben und an eine zugehörige Funktion weitergegeben, deren Warnungen angezeigt werden.
Dabei wird über die folgende zugehörige Funktion ein
einfacher sicherer Interpreter
verwendet (Abbildung 9.7),
der die Anweisungen in den Datensätzen auswertet und
über einen alias
Mechanismus vereinbarte zulässige
Elemente erkennen kann.
proc mySafeOpenSource {FileName} { global w set canvParserSource \ [interp create -safe] proc canvas_parser_cmd {w args} { eval $w $args } $canvParserSource alias \ .f.sub.c canvas_parser_cmd $w set F [open $FileName r+] set ToBeSafeScript [read $F] close $F $canvParserSource eval \ set w .f.sub.c $canvParserSource eval \ $ToBeSafeScript interp delete $canvParserSource } |
Abbildung 9.7: Anwendungsbeispiel: Benutzerdefinierte Nutzung eines sicheren Interpreters in einer Komponente
Enthält ein geöffneter Datensatz Anweisungen wie
source
oder exec
,
so werden diese nicht ausgeführt und stattdessen
wird eine Warnung erzeugt, die von der aufrufenden Funktion ausgegeben
wird. Alle kritischen Sprachelemente sind durch
den sicheren Interpreter abgedeckt.
Eine Erweiterung um individuelle Befehle, die beispielsweise
benutzerdefiniert als Tcl/Tk Funktion implementiert
oder als Routine in den verwendeten Interpreter integriert ist,
wäre auf Basis eines sicheren Interpreters ebenso einfach möglich.
In ähnlicher Weise kann der Benutzer
Funktionen zum Speichern von Daten
sehr einfach für spezifische Gegebenheiten selbst gestalten.
Eine nützliche Funktionalität ist z.B. die Auswertung eines
Attributs bestimmter Objekte, z.B. canvas_save_ignore
,
welches bewirkt, daß das Speichern dieser Objekte unterbunden
wird. Dies kann z.B. für Objekte zum Einsatz kommen, die nur
temporär in einer interaktiven Darstellung vorhanden sein sollen.
Daten, die durch solche Funktionen hantiert werden können, wurden für den Prototyp als ,,GIS Active Source`` ( GAS , .gas) bezeichnet.
Die Nutzung eines teilweise nativen Formates ist ebenso möglich, erfordert aber etwas mehr Aufwand, da möglicherweise einige Elemente erst durch Funktionen zusammengebaut werden müssen (dies wird auf Seite näher erläutert).
Eine weitere Möglichkeit ist ein Speicherabzug (engl.: ,,dump``) des aktuellen Canvas. Dabei werden alle notwendigen Informationen über Objekte, Eigenschaften usw. abgegriffen. Diese Informationen sind dann beliebig zu verarbeiten, also z.B. in eine Datei schreibbar oder in einer Variable oder einem Datenfeld speicherbar. Auf diese Art läßt sich beispielsweise ein beliebiger Zustand des Canvas später wiederherstellen. Dies kann bei Funktionalitäten wie ,,Rückgängig machen`` (engl.: ,,undo``), aber auch flexibler für Schnappschüsse von Bearbeitungsschritten oder Überlagerungen von Zuständen Anwendung finden.
Für den Prototyp wurde dieser Typ von Daten als ,,Canvas Daten`` ( CAN , can) bezeichnet.