XCommunicationsImpl.mesa
Copyright Ó 1988, 1989, 1991 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, July 29, 1988 5:51:46 pm PDT
Christian Jacobi, March 1, 1989 9:42:32 am PST
DIRECTORY
Ascii, Atom, XCommunications, IO, Rope, SymTab;
XCommunicationsImpl:
CEDAR MONITOR
IMPORTS Atom, Rope, SymTab
EXPORTS XCommunications
SHARES IO
~ BEGIN OPEN XCommunications;
Error: PUBLIC ERROR [what: Rope.ROPE] = CODE;
protocolsReg: SymTab.Ref Ź SymTab.Create[case: FALSE];
applicationsReg: Atom.PropList Ź NIL; --elements PropList's again
RegisterCommunication:
PUBLIC PROC [protocolData: ProtocolData] = {
protocolData.success Ź TRUE;
[] Ź SymTab.Store[protocolsReg, Atom.GetPName[protocolData.protocol], NEW[ProtocolDataŹprotocolData]];
};
RegisterScanSpecific:
PUBLIC ENTRY PROC [application:
ATOM, protocol:
ATOM, scan: ScanProcType] = {
protocolsForApp: Atom.PropList Ź NARROW[Atom.GetPropFromList[applicationsReg, application]];
protocolsForApp Ź Atom.PutPropOnList[protocolsForApp, protocol, NEW[ScanProcType Ź scan]];
applicationsReg Ź Atom.PutPropOnList[applicationsReg, application, protocolsForApp];
};
ScanName:
PUBLIC PROC [name: Rope.
ROPE]
RETURNS [sn: ScannedName Ź [
NIL,
NIL,
NIL]] = {
leng: INT Ź Rope.Length[name];
SkipChar:
PROC [pos:
INT]
RETURNS [
BOOL] = {
SELECT Rope.Fetch[name, pos]
FROM
Ascii.SP, Ascii.NUL, Ascii.FF, Ascii.LF, Ascii.CR, Ascii.TAB => RETURN [TRUE];
ENDCASE => RETURN [FALSE];
};
SubString:
PROC [first, firstNot:
INT]
RETURNS [r: Rope.
ROPEŹNIL] = {
firstNot Ź MIN[firstNot, leng];
WHILE firstNot>first AND SkipChar[first] DO first Ź first+1 ENDLOOP;
WHILE firstNot>first AND SkipChar[firstNot-1] DO firstNot Ź firstNot-1 ENDLOOP;
IF firstNot>first THEN r Ź Rope.Substr[name, first, firstNot-first];
};
pos1, pos2: INT;
pos1 Ź Rope.SkipTo[name, 0, "%"];
IF pos1<leng THEN {sn.protocol Ź SubString[0, pos1]; pos1 Ź pos1+1} ELSE pos1 Ź 0;
pos2 Ź Rope.SkipTo[name, pos1, ":"];
sn.server Ź SubString[pos1, pos2];
IF pos2<leng THEN {pos2 Ź pos2+1};
sn.specific Ź SubString[pos2, LAST[INT]];
};
GetProtocol:
PUBLIC PROC [protocol: Rope.
ROPE, defaultProtocol:
ATOM Ź
NIL]
RETURNS [pd: ProtocolData Ź []] = {
IF Rope.IsEmpty[protocol]
AND defaultProtocol#
NIL THEN
protocol Ź Atom.GetPName[defaultProtocol];
WITH SymTab.Fetch[protocolsReg, protocol].val
SELECT FROM
rpd: REF ProtocolData => pd Ź rpd;
ENDCASE => {};
};
GetScanner:
PROC [application:
ATOM, protocol:
ATOM]
RETURNS [scanner: ScanProcTypeŹ
NIL] = {
protocolsForApp: Atom.PropList Ź NARROW[Atom.GetPropFromList[applicationsReg, application]];
IF protocolsForApp#
NIL THEN
WITH Atom.GetPropFromList[protocolsForApp, protocol]
SELECT FROM
s: REF ScanProcType => scanner Ź s;
ENDCASE => {};
};
ScanSpecific:
PUBLIC PROC [application:
ATOM, protocol:
ATOM, scannedName: ScannedName]
RETURNS [base: Rope.
ROPE, port:
REF ANY] = {
scanner: ScanProcType;
IF protocol=
NIL THEN {
pd: ProtocolData Ź GetProtocol[scannedName.protocol];
IF pd.protocol=NIL OR ~pd.success THEN ERROR Error["protocol not registered"];
protocol Ź pd.protocol
};
scanner Ź GetScanner[application, protocol];
IF scanner=NIL THEN ERROR Error["application not registered"];
[base, port] Ź scanner[application, protocol, scannedName];
};
CreateStreams:
PUBLIC PROC [application:
ATOM, name: Rope.
ROPE, defaultProtocol:
ATOM Ź
NIL]
RETURNS [sd: StreamData] = {
base: Rope.ROPE; port: REF ANY;
scannedName: ScannedName Ź ScanName[name];
pData: ProtocolData Ź GetProtocol[scannedName.protocol, defaultProtocol];
IF NOT pData.success OR pData.create=NIL THEN {sd.errorMsg Ź "unknown protocol"; RETURN};
[base, port] Ź ScanSpecific[application, pData.protocol, scannedName ! Error => GOTO Oops];
[sd] Ź pData.create[base, port];
[sd] Ź FinishStreamData[sd];
EXITS Oops => sd.errorMsg Ź "application does not support protocol";
};
FinishStreamData:
PUBLIC PROC [sd: StreamData]
RETURNS [d: StreamData] = {
IF sd.success
THEN {
IF sd.in=
NIL OR sd.out=
NIL THEN {
sd.success Ź FALSE; IF Rope.IsEmpty[sd.errorMsg] THEN sd.errorMsg Ź "no streams created"
}
ELSE {
IF sd.putChar=NIL THEN sd.putChar Ź sd.out.streamProcs.putChar;
IF sd.unsafePutBlock=NIL THEN sd.unsafePutBlock Ź sd.out.streamProcs.unsafePutBlock;
IF sd.getChar=NIL THEN sd.getChar Ź sd.in.streamProcs.getChar;
IF sd.sendNow=NIL THEN sd.sendNow Ź sd.out.streamProcs.flush;
IF sd.errorFromStream=NIL THEN sd.errorFromStream Ź DefaultErrorFromStream;
}
};
RETURN [sd];
};
DefaultErrorFromStream:
PROC [self:
IO.
STREAM]
RETURNS [Rope.
ROPE] = {
RETURN ["failure"];
};
END.