DFInternal.mesa
last edited by Levin on December 16, 1983 2:05 pm
DIRECTORY
DFOperations USING [InfoClass, InteractionProc],
DFUtilities USING [Date],
FS USING [ErrorDesc],
IO USING [STREAM],
Rope USING [ROPE];
DFInternal: CEDAR DEFINITIONS =
BEGIN
OPEN Ops: DFOperations, Utils: DFUtilities;
ROPE: TYPE = Rope.ROPE;
Interaction Stuff
Client: TYPE = REF ClientDescriptor;
ClientDescriptor: TYPE = RECORD [
proc: Ops.InteractionProc,
data: REF ANY, -- to be passed as 'clientData' parameter of 'proc'
log: IO.STREAM
];
SimpleInteraction: PROC [client: Client, interaction: REF ANY];
Used for any `interaction' that doesn't expect a response. SimpleInteraction handles any client-requested abort internally, with 'DoAbort' being invoked. Note that if ISTYPE[interaction, REF Ops.InfoInteraction] = TRUE and interaction.class = $abort, abort processing does NOT occur; that is, SimpleInteraction returns normally to its caller. This is because SimpleInteraction doesn't discriminate on the interaction type.
YesOrNo: PROC [client: Client, message: ROPE, default: BOOL, blunder: BOOLFALSE]
RETURNS [BOOL];
Used for Ops.YesNoInteraction. Abort processing is handled internally, with 'DoAbort' being invoked.
DoInteraction: PROC [client: Client, interaction: REF ANY] RETURNS [response: REF ANY];
Used for the general case, including (for now) Ops.ChoiceInteraction. DoInteraction handles any client-requested abort internally, with 'DoAbort' being invoked. Note that if ISTYPE[interaction, REF Ops.InfoInteraction] = TRUE and interaction.class = $abort, abort processing does NOT occur; that is, DoInteraction returns normally to its caller. This is because DoInteraction doesn't discriminate on the interaction type.
CheckAbort: PROC [client: Client];
interacts with the client and, if an abort is requested, triggers 'DoAbort'.
DoAbort: PROC [
log: IO.STREAM,
message: ROPENIL, proc: Ops.InteractionProc ← NIL, clientData: REF ANYNIL];
If 'proc' and 'message' are non-NIL, an InfoInteraction occurs. The message is then logged on 'log'. Finally, AbortDF is raised.
AbortDF: ERROR;
raised only by DoAbort.
DefaultInteractionProc: Ops.InteractionProc;
to be used when callers of DFOperations procedures have 'interact' = NIL.
File Info Stuff
LocalFileInfo: TYPE = RECORD [
name: ROPE,
attachedTo: ROPE,
date: Utils.Date ← [],
keep: INT ← -1
];
RemoteFileInfo: TYPE = RECORD [
name: ROPE,
date: Utils.Date ← []
];
GetFileInfo: PROC [
info: REF ANY, notFoundOK: BOOLFALSE, remoteCheck: BOOLFALSE,
client: Client ← NIL, errorLevel: Ops.InfoClass ← $error];
'info' must be either REF LocalFileInfo or REF RemoteFileInfo.
Behavior for ISTYPE[info, REF LocalFileInfo] = TRUE: info.name is assumed to describe a local file. If info.date.format ~= $explicit, any trailing version number on info.name is stripped off; otherwise the version number is retained (even if info.date.gmt = BasicTime.nullGMT; this permits a lookup with "version number as truth"). The file is looked up and, if found, info.date.format is set to $explicit and info.date.gmt is set to the file's create date. The remoteCheck parameter is passed to FS; thus, if a local file is attached to a remote file and remoteCheck = TRUE, the server will be interrogated to ensure that the file exists remotely. In any case, if the file doesn't exist and notFoundOK is TRUE, info.date is set to [$omitted, BasicTime.nullGMT]. All other cases trigger error handling, discussed below.
Behavior for ISTYPE[info, REF RemoteFileInfo] = TRUE: The remote file specified by info.name and info.date is looked up, using a create time search on info.date.gmt if info.date.format = $explicit. The remoteCheck parameter is ignored. If the file exists, info.date.format is set to $explicit and info.date.gmt is set to the file's create date. If the file doesn't exist and notFoundOK is TRUE, info.date is set to [$omitted, BasicTime.nullGMT]. All other cases trigger error handling, discussed below.
Error handling: Except as described above, all occurrences of FS.Error propagate to the client. However, if the caller supplies a non-NIL value for 'client', substantial error handling will first occur internally. In this case (client ~= NIL), RetryFSOperation will be called. If it returns TRUE, GetFileInfo will be (re)executed in its entirety. If RetryFSOperation returns FALSE, ReportFSError will be called with the obvious parameters. Note that if ReportFSError is invoked and errorLevel = $abort, AbortDF will be raised (see description of ReportFSError, below).
LocalFile: PROC [file: ROPE] RETURNS [BOOL];
ShortName: PROC [file: ROPE, keepVersion: BOOLFALSE] RETURNS [ROPE];
Error Handling
RetryFSOperation: PROC [error: FS.ErrorDesc, client: Client] RETURNS [retry: BOOL];
determines whether a retry of an FS operation is appropriate. Any necessary waiting has been done inside this procedure (client can simply say RETRY in catch phrase).
ReportFSError: PROC [
error: FS.ErrorDesc, info: REF ANY, client: Client, errorLevel: Ops.InfoClass ← $error];
'info' is either REF LocalInfo or REF RemoteInfo. SimpleInteraction is invoked with an Ops.InfoInteraction at the specified errorLevel. Then, if errorLevel = $abort, DoAbort[client.log] is invoked, causing AbortDF to be raised.
END.