implementation module receivertable import StdBool, StdInt, StdMisc import StdMaybe, commondef, id, systemid, device :: ReceiverTable // The table of all receivers :== [ReceiverTableEntry] :: ReceiverTableEntry = { rteLoc :: !RecLoc // The location of the receiver , rteSelectState :: !SelectState // The current SelectState of the receiver , rteASMCount :: !Int // The current size of asynchronous message queue of the receiver } :: RecLoc = { rlIOId :: !SystemId // Id of parent process , rlDevice :: !Device // Device kind of parent , rlParentId :: !Id // Id of parent device instance , rlReceiverId :: !Id // R(2)Id of the receiver itself } initialReceiverTable :: *ReceiverTable // initialReceiverTable yields an empty ReceiverTable initialReceiverTable = [] eqReceiverId :: !Id !RecLoc -> Bool // receivers are added uniquely by their rlReceiverId eqReceiverId id {rlReceiverId} = id==rlReceiverId /* addReceiverToReceiverTable adds a new receiver entry to the ReceiverTable. The Boolean result is True iff no duplicate receiver entry was found, otherwise it is False. */ addReceiverToReceiverTable :: !ReceiverTableEntry !*ReceiverTable -> (!Bool,!*ReceiverTable) addReceiverToReceiverTable rte=:{rteLoc={rlReceiverId}} receivers = add rlReceiverId rte receivers where add :: !Id !ReceiverTableEntry !*[ReceiverTableEntry] -> (!Bool,!*[ReceiverTableEntry]) add rid entry [rte=:{rteLoc}:rtes] | eqReceiverId rid rteLoc = (False,[rte:rtes]) | otherwise # (isnew,rtes) = add rid entry rtes = (isnew,[rte:rtes]) add _ entry _ = (True,[entry]) /* removeReceiverFromReceiverTable removes a receiver identified by Id from the ReceiverTable. The Boolean result is True iff an entry was actually removed, otherwise it is False. */ removeReceiverFromReceiverTable :: !Id !*ReceiverTable -> (!Bool,!*ReceiverTable) removeReceiverFromReceiverTable rid receivers = (found,receivers`) where (found,_,receivers`) = remove (\{rteLoc}->eqReceiverId rid rteLoc) undef receivers /* getReceiverTableEntry returns the receiver identified by Id from the ReceiverTable. If such a receiver could be found, then (Just ReceiverTableEntry) is returned, otherwise Nothing. */ getReceiverTableEntry :: !Id !*ReceiverTable -> (!Maybe ReceiverTableEntry,!*ReceiverTable) getReceiverTableEntry rid [rte=:{rteLoc}:rtes] | eqReceiverId rid rteLoc = (Just rte,[rte:rtes]) | otherwise # (maybeRTE,rtes) = getReceiverTableEntry rid rtes = (maybeRTE,[rte:rtes]) getReceiverTableEntry _ [] = (Nothing,[]) /* setReceiverTableEntry replaces the current ReceiverTableEntry that has an identical Id. If such an entry could not be found, then the new entry is added behind all other entries. */ setReceiverTableEntry :: !ReceiverTableEntry !*ReceiverTable -> *ReceiverTable setReceiverTableEntry rte=:{rteLoc={rlReceiverId}} receivers = set rlReceiverId rte receivers where set :: !Id !ReceiverTableEntry !*[ReceiverTableEntry] -> *[ReceiverTableEntry] set rid new [rte=:{rteLoc}:rtes] | eqReceiverId rid rteLoc = [new:rtes] | otherwise # rtes = set rid new rtes = [rte:rtes] set _ new _ = [new] /* getActiveReceiverTableEntry returns (Just Id) of the first receiver in the ReceiverTable which rteSelectState==Able and rteASMCount>0. If such an entry could not be found, then Nothing is returned. */ getActiveReceiverTableEntry :: !*ReceiverTable -> (!Maybe Id,!*ReceiverTable) getActiveReceiverTableEntry [rte=:{rteSelectState,rteASMCount,rteLoc}:rtes] | enabled rteSelectState && rteASMCount>0 #! id = rteLoc.rlReceiverId = (Just id,[rte:rtes]) | otherwise # (maybeId,rtes) = getActiveReceiverTableEntry rtes = (maybeId,[rte:rtes]) getActiveReceiverTableEntry [] = (Nothing,[])