Universität Ulm,
Fakultät für Mathematik und Wirtschaftswissenschaften,
SAI
WS 97/98 || Entwicklung objekt-orientierter Bibliotheken || Beispiele || Collections-13
MODULE Collections
MODULE Collections;
IMPORT Disciplines, Events, RelatedEvents;
TYPE
Collection = POINTER TO CollectionRec;
(* Schnittstelle fuer Implementierungen *)
TYPE
Message = RECORD END;
AddProc = PROCEDURE (collection: Collection; object: Disciplines.Object);
FirstProc = PROCEDURE (collection: Collection);
NextProc = PROCEDURE (collection: Collection;
VAR object: Disciplines.Object) : BOOLEAN;
GetProc = PROCEDURE (collection: Collection;
index: INTEGER; VAR object: Disciplines.Object);
RemoveProc = PROCEDURE (collection: Collection;
object: Disciplines.Object) : BOOLEAN;
HandlerProc = PROCEDURE (collection: Collection;
VAR message: Message);
Interface = POINTER TO InterfaceRec;
InterfaceRec =
RECORD
add: AddProc; (* required *)
first: FirstProc; (* required *)
next: NextProc; (* required *)
get: GetProc; (* optional *)
remove: RemoveProc; (* optional *)
handler: HandlerProc; (* optional *)
END;
CONST
get = 0; remove = 1; handler = 2;
TYPE
Capability = SHORTINT; (* get..handler *)
CapabilitySet = SET; (* OF Capability *)
TYPE
CollectionRec =
RECORD
(Disciplines.ObjectRec)
(* private Komponenten *)
if: Interface;
caps: CapabilitySet;
END;
(* error handling *)
CONST
objectNotInCollection = 0;
(* Collections.Remove failed because
the object is not in the collection
*)
badIndex = 1;
(* Collections.Get failed because of an invalid index *)
errors = 2;
TYPE
ErrorCode = SHORTINT;
ErrorEvent = POINTER TO ErrorEventRec;
ErrorEventRec =
RECORD
(Events.EventRec)
errorcode: ErrorCode; (* what happened...? *)
collection: Collections.Collection;
(* failed operation was called for this collection *)
object: Disciplines.Object;
(* the parameter, if present (may be NIL otherwise) *)
END;
VAR
error: Events.EventType;
errormsg: ARRAY errors OF Events.Message;
(* error message texts for all error codes returned by this module *)
PROCEDURE InitErrorHandling;
BEGIN
Events.Define(error);
errormsg[objectNotInCollection] :=
"object is not member of the collection";
errormsg[badIndex] := "invalid index";
END InitErrorHandling;
PROCEDURE Error(collection: Collection;
object: Disciplines.Object; (* may be NIL *)
errorcode: ErrorCode);
VAR
event: ErrorEvent;
BEGIN
NEW(event);
event.type := error;
event.message := errormsg[errorcode];
event.errorcode := errorcode;
event.collection := collection;
event.object := object;
RelatedEvents.Raise(collection, event);
END Error;
PROCEDURE Init(collection: Collection; if: Interface; caps: CapabilitySet);
BEGIN
ASSERT((if.add # NIL) & (if.first # NIL) & (if.next # NIL));
ASSERT(~(get IN caps) OR (if.get # NIL));
ASSERT(~(handler IN caps) OR (if.handler # NIL));
collection.if := if;
collection.caps := caps;
END Init;
PROCEDURE Send(collection: Collection; VAR message: Message);
BEGIN
ASSERT(handler IN collection.caps);
collection.if.handler(collection, message);
END Send;
(* Schnittstelle fuer Klienten *)
PROCEDURE Capabilities(collection: Collection) : CapabilitySet;
BEGIN
RETURN collection.caps
END Capabilities;
PROCEDURE Add(collection: Collection; object: Disciplines.Object);
BEGIN
collection.if.add(collection, object);
END Add;
PROCEDURE First(collection: Collection);
BEGIN
collection.if.first(collection);
END First;
PROCEDURE Next(collection: Collection;
VAR object: Disciplines.Object) : BOOLEAN;
BEGIN
RETURN collection.if.next(collection, object)
END Next;
PROCEDURE Get(collection: Collection;
index: INTEGER; VAR object: Disciplines.Object);
BEGIN
ASSERT(get IN collection.caps);
collection.if.get(collection, index, object);
IF object = NIL THEN
Error(collection, NIL, badIndex);
END;
END Get;
PROCEDURE Remove(collection: Collection; object: Disciplines.Object);
(* wird nicht von allen Implementierungen unterstuetzt *)
BEGIN
ASSERT(remove IN collection.caps);
IF ~collection.if.remove(collection, object) THEN
Error(collection, object, objectNotInCollection);
END;
END Remove;
BEGIN
InitErrorHandling;
END Collections.
WS 97/98 || Entwicklung objekt-orientierter Bibliotheken || Beispiele || Collections-13
Andreas Borchert, 6. Dezember 1997