Neben dem mittlerweile etablierten XBRA-Protokoll, das wir Ihnen im vorherigen Artikel vorgestellt haben, existiert seit TOS 1.6 (STE) der Cookie-Jar (die Keksdose). Dabei handelt es sich um eine Informationsstruktur. Mit ihrer Hilfe kann man verschiedene rechnerabhängige Informationen erhalten bzw. Informationen mit anderen Programmen austauschen.
Der Cookie-Jar befindet sich irgendwo im Speicher des Rechners. Auf seine Startadresse zeigt die Systemvariable _p_cookies (Adresse: $5A0). Die einzelnen Kekse (Cookies) bestehen aus zwei 32-Bit-Werten (Im ATARI-Slang ist Cookie ein gebräuchlicher Terminus für eine 32 Bits große Codenummer). Der erste Wert stellt die Cookie-Kennung (cookie_id\ siehe Bild 1) dar. Der zweite Wert ist abhängig vom jeweiligen Cookie (siehe Tabelle 1).
Da der Cookie-Jar erst ab TOS 1.6 vom Betriebssystem automatisch installiert (und beim Reset wieder gelöscht) wird, muß er bei früheren Versionen von einem residenten Programm installiert werden.
Wenn man mit Cookies arbeiten will, muß man als erstes einmal nachsehen, ob es sie überhaupt gibt. Steht in der Systemvariablen j>_cookies ein NULL-Zeiger, bedeutet dies, daß (noch) kein Cookie-Jar installiert ist. Hat man einen Zeiger bekommen, kann man die Tabelle gezielt nach einem Cookie durchsuchen, um entsprechende Informationen zu erhalten, einen neuen Cookie einzutragen oder einen Eintrag zu löschen.
Sie fragen sich, was für einen Sinn solch eine Tabelle hat? Nun, zum einen erhält man einige wichtige Informationen über die Rechnerkonfiguration (siehe nochmal Tabelle 1), und zum zweiten kann man anderen Programmen mitteilen, ob ein bestimmtes Programm installiert ist. Dazu sollte, wie beim XBRA-Verfahren, dieCookie-ID individuell sein. Bei der Namensgebung sind drei Punkte zu beachten:
Wie bereits bei der XBRA-Bezeichnung, wird auch beim Cookie-Jar von Julian Reschke eine Liste der bereits verwendeten IDs geführt.
Im Langwort cookie_value kann eine beliebige Information abgelegt werden, z.B. ein Zeiger auf eine interne Programmstruktur [über die andere Programme beispielsweise bestimmte Betriebsparameter verstellen können (dies ist beim Mausbeschleuniger MACCEL3 der Fall)], auf einen Text oder sonst etwas; der Phantasie sind hier keine Grenzen gesetzt!
Es versteht sich natürlich von selbst, daß die Bedeutung von cookie_value irgendwo dokumentiert sein sollte! (Was nützt schon ein Eintrag, wenn man nicht weiß, wozu er zu gebrauchen ist?)
Die Aufmerksamen unter Ihnen werden jetzt wahrscheinlich fragen, wieviele Cookies denn eigentlich in den Jar hineinpassen? Diese Frage kann nicht pauschal beantwortet werden, da der Speicherbereich, auf den _p_cookies verweist, ja an beliebiger Stelle im Speicher steht und somit irgendwann mittels Malloc (oder einer ähnlichen Funktion) angefordert wurde - die Größe des Jars ist also variabel!
Um aber trotzdem das Ende der Tabelle erkennen zu können, existiert ein sogenannter NULL-Cookie (ID: $00000000), der als Wert die maximale Anzahl der in den Jar reinpassenden Cookies enthält. Außerdem ist er der letzte der aktuellen Cookie-Liste.
Soweit die Theorie. Schauen wir uns einige Beispiele an, die die Nützlichkeit dieses Verfahrens noch einmal unterstreichen sollen. Besonders wichtig (im Hinblick auf portable Programmierung) ist es z.B., festzustellen, ob ein bestimmtes Programm auf einem normalen ST, einem getuneten Rechner (etwa mit einem 68020-Prozessor) oder gar auf dem TT läuft. Dank der vom BIOS installierten System-Cookies [erst ab TOS 1.6; vorher muß selbst installiert werden (siehe Programm auf der Diskette)] ist es nun kein Problem mehr, festzustellen, auf welchem Rechner-Typ und mit welchem Prozessor das Programm läuft.
Aufgrund der außerordentlichen Nützlichkeit dieses Verfahrens bot es sich an, einige Hilfsroutinen zu schreiben, die den Umgang mit Cookies erleichtern sollen. Diese finden Sie, neben einem Beispiel, auf den Disketten zum Heft. Das Beispiel demonstriert einen Anwendungsfall von Cookies: Wie kann ein Programm feststellen, ob es sich bereits installiert hat? Einige der im Listing verwendeten Funktionen stammen aus dem Cookie-Modul; in der Praxis dürfte es sich als nützlich erweisen, dieses Modul getrennt zu übersetzen und in einer LIB-Datei festzuhalten. Bei einer Programmentwicklung wird dann diese Datei automatisch vom Projektmanager an den Linker weitergereicht...
Kommen wir aber zu den eigentlichen Hilfroutinen des Moduls. Sie übernehmen die wichtigsten Operationen, die beim Umgang mit Cookies auftreten können (Erzeugen, Einträgen, Abfragen, Löschen etc.).
Ein neuer Cookie kann ganz einfach mit Hilfe der Funktion create_cookie() erstellt werden; man übergibt dieser dazu lediglich einen Zeiger auf eine COOKIE-Struktur, die Programmmkennung (cookiejd) sowie den Wert des Cookies (longl). Der so erzeugte Cookie kann mittels new_cookie in den hoffentlich vorhandenen Cookie-Jar eingetragen werden.
Mit Hilfe von get_cookieQ kann überprüft werden, ob ein bestimmter Cookie bereits im System vorhanden ist (Return-Wert = TRUE); in diesem Fall wird auch gleich der zugehörige Wert in der Variablen value mitgeliefert.
Das Löschen von Cookies (das kann beispielsweise dann notwendig sein, wenn das Programm, das diesen installiert hat, sich wieder aus dem Speicher entfernen will) übernimmt die Funktion remove_cookie(). Gelöscht wird übrigens einfach dadurch, daß - nachdem die Cookie-ID gefunden wurde, alle folgenden Cookies (einschließlich des abschließenden NULL-Cookies) eine Position nach oben verrückt werden.
move_cookiejar() ermöglicht es, den kompletten Jar an eine neue Speicherstelle zu kopieren (der zweite Parameter gibt dabei die evtl, neue Größe des Jars an), und cookie_size() liefert die Größe des Jars, d.h. die Anzahl der maximal in ihn hineinpassenden Cookies. Zu guter Letzt kann der Inhalt des gesamten Cookie Jars noch mittels print_cookie() auf die Standardausgabeeinheit ausgegeben werden.
Aufruf: create_cookie(cookie, id, value)
Funktion: initialisiert einen Cookie
Parameter: cookie: Zeiger auf COOKIE-Struktur
id: (ASCII-)Kennzeichnung des Cookies (vier Zeichen)
value: Wert des Cookies
Rückgabewert: keiner
Aufruf: new_cookie (entry)
Funktion: trägt neuen Cookie in den Jar ein
Parameter: entry: Zeiger auf einzutragenden Cookie
Rückgabewert: TRUE, wenn ok: FALSE im Fehlerfall
Aufruf: get_cookie(id, value)
Funktion: liefert den Wert eines Cookies
Parameter: id: (ASCII-)Kennzeichnung des Cookies (vier Zeichen)
value: Zeiger für Wert des Cookies
Rückgabewert: TRUE, wenn ok; FALSE, wenn Cookie nicht existiert
Aufruf: remove_cookie(id)
Funktion: entfernt einen Cookie
Parameter: id: (ASCII-)Kennzeichnung des Cookies (vier Zeichen)
Rückgabewert: TRUE, wenn ok; FALSE, wenn Cookie nicht existiert
Aufruf: move_cookiejar(dest, size)
Funktion: verschiebt kompletten Jar an neue Speicherstelle; evtl. Vergrößerung der Anzahl der möglichen Einträge
Parameter: dest: neue Adresse für Jar
size: neue Größe des Jars
Rückgabewert: keiner
Aufruf: cookie_size()
Funktion: liefert die Anzahl der maximal möglichen Einträge in den installierten Jar
Parameter: keine
Rückgabewert: Anzahl der maximal möglichen Cookies
Aufruf: print_size()
Funktion: gibt Inhalt des Jars aus Standardausgabe aus
Parameter: keine
Rückgabewert: keiner
typedef struct {
char cookie_id[4]; /* Cookie-Kennung - 4 ASCII-Zeichen */
long cookie_value; /* Wert des Cookies */
} COOKIE;
Bild 1: Die Cookie-Struktur in C
ID | Bedeutung |
---|---|
_CPU | Prozessortyp: Die Werte 0,10, 20, 30 und 40 stehen für die Prozessoren 68000,68010,68020,68030 und 68040. |
_FPU | FPU-Typ: das obere Wort gibt Auskunft über das Vorhandensein eines Floating-Point-Koprozessors und über die Unterstützungsart des Betriebssystems bei Fließkommazahlenrechnung: |
Bit 0: gesetzt wenn FPU-Zusatzkarte (z.B. SFP 004 von ATARI) vorhanden ist; 68881 als Peripheriebaustein (ST und STE)
Bit 1+2: Koprozessortyp (68881 oder 68882):
0: weder noch
1: 68881 oder 68882 (Typ unbekannt)
2:68881 3: 68882 Bit 3: gesetzt wenn 68040
__FRB Fast-RAM-Buffer (TT): Zeiger auf einen 64-KByte-Puffer im ST-RAM, der als Zwischenspeicher beim normalen ACSI-DMA-Transfer dient.
_MCH Maschinentyp; das obere Wort bezeichnet die Rechnerfamilie
0: ST (520ST, 1040ST oder Mega ST)
1: STE (1040 STE und Mega STE)
2: TT
_SND Soundhardware:
Bit 0 gesetzt, wenn normaler Soundchip (Gl/Yamaha) vorhanden
Bit 1 gesetzt, wenn Stereo-DMA-Chip vorhanden (STE und TT)
_SWI DIP-Switch: Werte des internen DIP-Schalters, sofern vorhanden
_VDO Video-Hardware: Das obere Wort beschreibt die Art der Video-Hardware:
0: ST 1: STE 2: TT
Außer den bisher aufgeführten Cookies, die ab TOS1.6 automatisch installiert werden, verwendet ATARI folgende weitere Cookies:
_FDC Informationen über Floppy-Controiler. Oberstes Byte erteilt Auskunft über die maximale Schreibdichte:
0: normal (720 KB) 1: High-Density (1,44 MB) 2: Extra High Density (2,88 MB)
Die unteren drei Bytes sind eine Herstellerkennung.
_FLK GEMDOS verfügt über FILE-LOCKING-Erweiterungen; Wert ist Versionsnummer der Erweiterung
JNF STEFIX (Patch-Programm für TOS 1.06) ist installiert
_NET GEMDOS-Netzwerkerweiterung; Wert ist ein Zeiger auf die Herstellerkennung und -versionsnummer
_OOL POOLFIX3 (Patch-Programm für GEMDOS 0.15) ist installiert
_SLM Diablo-Treiber für SLM-Laserdrucker ist installiert
Tabelle 1: Die System-Cookies