<> <> <> <> <<>> DIRECTORY BasicTime, IO, FS, Rope, PDRemoteStream, STP; PDRemoteStreamLocalStub: PROGRAM IMPORTS FS, IO, Rope, STP EXPORTS PDRemoteStream = BEGIN Error: PUBLIC ERROR [expl: ROPE, retryable: BOOL] = CODE; ROPE: TYPE ~ Rope.ROPE; Retryable: PROC [local: BOOL, code: ATOM, stpCode: STP.ErrorCode] RETURNS [BOOL] = { IF local THEN RETURN [SELECT code FROM $connectionTimedOut, $connectionRejected => TRUE, ENDCASE => FALSE]; RETURN [SELECT stpCode FROM connectionTimedOut, connectionRejected, connectionClosed, noConnection, noNameLookupResponse => TRUE, ENDCASE => FALSE]; }; Lookup: PUBLIC PROC [fileName: ROPE, createDate: BasicTime.GMT, name, password: ROPE] RETURNS [bytes: INT, createDateRope: ROPE] = { BEGIN ENABLE UNWIND => {}; time: BasicTime.GMT; [bytes: bytes, created: time] _ FS.FileInfo[fileName ! FS.Error => Error[expl: error.explanation, retryable: FALSE]]; createDateRope _ IO.PutR[IO.time[time]]; END; }; Read: PUBLIC PROC [fileName: ROPE, name, password: ROPE, action: PROC[IO.STREAM]] = { MyRead[fileName, name, password, action ! FS.Error => ERROR Error[expl: error.explanation, retryable: Retryable[TRUE, error.code, undefinedError]]]; }; MyRead: PROC [fileName: ROPE, name, password: ROPE, action: PROC[IO.STREAM]] = { stream: IO.STREAM _ NIL; cp: FS.ComponentPositions; server: ROPE; [fileName, cp] _ FS.ExpandName[fileName ! FS.Error => ERROR Error[expl: error.explanation, retryable: Retryable[TRUE, error.code, undefinedError]]]; server _ Rope.Substr[fileName, cp.server.start, cp.server.length]; BEGIN ENABLE UNWIND => {IF stream # NIL THEN {IO.Close[stream]; stream _ NIL}}; IF Rope.IsEmpty[server] THEN BEGIN stream _ FS.StreamOpen[fileName]; action[stream]; stream.Close[]; stream _ NIL; RETURN; END; END; BEGIN stp: STP.Handle _ STP.Create[]; open: BOOL _ FALSE; BEGIN ENABLE UNWIND => {IF open THEN stp.Close[ ! STP.Error => TRUSTED {CONTINUE}]; IF stream # NIL THEN {IO.Close[stream]; stream _ NIL}}; [] _ stp.Open[server]; open _ TRUE; stp.Login[name, password]; stream _ stp.CreateRemoteStream[Rope.Substr[fileName, cp.dir.start-1], read]; action[stream]; stp.Close[ ! STP.Error => TRUSTED {CONTINUE}]; IO.Close[stream]; stream _ NIL END; END; }; END.