Oberon || Library || Module Index || Search Engine || Definition || Module
TYPE Name = ConstStrings.String; TYPE Node = POINTER TO NodeRec; TYPE NodeRec = RECORD (Services.ObjectRec) END; TYPE Lister = Iterators.Iterator;
CONST examine = 0; CONST change = 1; CONST read = 2; CONST search = 3; CONST insert = 4; CONST delete = 5; CONST destroy = 6; CONST accessmodes = 7; TYPE AccessMode = SHORTINT; (* [examine..destroy] *) TYPE Permissions = ARRAY accessmodes OF Shards.Pot; TYPE Status = POINTER TO StatusRec; TYPE StatusRec = RECORD (Objects.ObjectRec) perm: Permissions; END;
TYPE AccessProc = PROCEDURE (node: Node; mode: AccessMode; auth: Shards.Lid): BOOLEAN; TYPE GetStatusProc = PROCEDURE (node: Node; auth: Shards.Lid; VAR status: StatusRec): BOOLEAN; TYPE SetStatusProc = PROCEDURE (node: Node; status: Status; auth: Shards.Lid): BOOLEAN; TYPE GetMembersProc = PROCEDURE (node: Node; auth: Shards.Lid; VAR members: Lister): BOOLEAN; TYPE TakeInterestProc = PROCEDURE (node: Node; auth: Shards.Lid; VAR eventType: Events.EventType): BOOLEAN; TYPE GetNodeProc = PROCEDURE (node: Node; name: Name; auth: Shards.Lid; VAR subnode: Node): BOOLEAN; TYPE InsertProc = PROCEDURE (node, subnode: Node; name: Name; auth: Shards.Lid): BOOLEAN; TYPE MakeSubnodeProc = PROCEDURE (node: Node; name: Name; status: Status; caps: CapabilitySet; auth: Shards.Lid; VAR subnode: Node): BOOLEAN; TYPE DeleteProc = PROCEDURE (node: Node; name: Name; auth: Shards.Lid): BOOLEAN; TYPE DestroyProc = PROCEDURE (node: Node; auth: Shards.Lid): BOOLEAN;
TYPE Interface = POINTER TO InterfaceRec; TYPE InterfaceRec = RECORD (Objects.ObjectRec) access: AccessProc; getStatus: GetStatusProc; setStatus: SetStatusProc; getMembers: GetMembersProc; takeInterest: TakeInterestProc; getNode: GetNodeProc; insert: InsertProc; makeSubnode: MakeSubnodeProc; delete: DeleteProc; destroy: DestroyProc; END;
CONST accessCap = 0; CONST statusCap = 1; CONST domainCap = 2; CONST destroyCap = 3; CONST makeSubnodeCap = 4; CONST allCaps = {accessCap .. makeSubnodeCap}; CONST strictCaps = {statusCap, domainCap, makeSubnodeCap}; TYPE CapabilitySet = SET; (* of [accessCap..destroyCap] *)
CONST inserted = insert; CONST deleted = delete; TYPE State = SHORTINT; (* inserted or deleted *) TYPE MemberEvent = POINTER TO MemberEventRec; TYPE MemberEventRec = RECORD (Events.EventRec) state: State; name: Name; (* of inserted/deleted member *) node: Node; END;
VAR root: Node;
TYPE ErrorCode = SHORTINT; TYPE ErrorEvent = POINTER TO ErrorEventRec; TYPE ErrorEventRec = RECORD (Events.EventRec) errorcode: ErrorCode; END; VAR errormsg: ARRAY errorcodes OF Events.Message; VAR error: Events.EventType;
PROCEDURE InitNode(node: Node; if: Interface; caps: CapabilitySet); PROCEDURE CreateNode(VAR node: Node; status: Status; caps: CapabilitySet); PROCEDURE Error(errors: RelatedEvents.Object; code: ErrorCode); PROCEDURE Capabilities(node: Node): CapabilitySet; PROCEDURE Access(node: Node; mode: AccessMode; auth: Shards.Lid): BOOLEAN; PROCEDURE GetStatus(node: Node; auth: Shards.Lid; VAR status: StatusRec): BOOLEAN; PROCEDURE SetStatus(node: Node; status: Status; auth: Shards.Lid): BOOLEAN; PROCEDURE GetMembers(node: Node; auth: Shards.Lid; VAR members: Lister): BOOLEAN; PROCEDURE TakeInterest(node: Node; auth: Shards.Lid; VAR eventType: Events.EventType): BOOLEAN; PROCEDURE GetNode(node: Node; name: Name; auth: Shards.Lid; VAR subnode: Node): BOOLEAN; PROCEDURE Insert(node, subnode: Node; name: Name; auth: Shards.Lid): BOOLEAN; PROCEDURE MakeSubnode(node: Node; name: Name; status: Status; caps: CapabilitySet; auth: Shards.Lid; VAR subnode: Node): BOOLEAN; PROCEDURE Delete(node: Node; name: Name; auth: Shards.Lid): BOOLEAN; PROCEDURE Destroy(node: Node; auth: Shards.Lid): BOOLEAN;
Nodes can have a combination of following capabilities:
A status, if maintained, contains authorization agents (of type Shards.Pot) controlling the use of following methods:
Access tries to guess whether node would allow a particular access mode mode. When in doubt, e.g. because node has no access capability, result is TRUE.
GetStatus examines the current status of node. SetStatus changes the status of node.
GetMembers reads from node all names of current subnodes.
TakeInterest returns an event type for events notifying changes (additions or deletions) of members. Different nodes will yield different event types. Notification events carry a reference to the domain node whose set of members has changed and the name of the member.
GetNode searches node for a direct subnode named name.
Insert inserts name name for subnode subnode into node.
MakeSubnode creates a subnode of the same type as node and inserts it into node. The initial status is defined by status. If set to NIL, subnode inherits its status from node. The set of supported capabilities of subnode is the intersection of caps and those of the corresponding implementation. The new subnode is returned in subnode.
Delete deletes name name for an existing subnode of node.
Destroy terminates node and deletes references to it wherever possible.
CreateNode can be used to create a node of standard behaviour. In that case, status may be NIL if no restrictions are required.
PROCEDURE PrintMembers(node: Names.Node; s: Streams.Stream); VAR members: Iterators.Iterator; member: Names.Name; BEGIN IF Names.domainCap in Names.Capabilities(node) THEN IF Names.GetMembers(node, NIL, members) THEN WHILE Iterators.Get(members, member) DO ConstStrings.Write(s, member); Write.LnS(s); END; ELSE Conclusions.Conclude(node, Errors.error, "PrintMembers"); END; END; END PrintMembers;
Trivial implementations (i.e. those with an empty set of capabilities) may pass a NIL value for if to InitNode.
Implementors are free to share the builtin Error procedure to raise error events as defined below.
Following error codes are currently implemented:
Oberon || Library || Module Index || Search Engine || Definition || Module