XNSFilingViewImpl.mesa
Copyright Ó 1990 by Xerox Corporation. All rights reserved.
Bill Jackson (bj), May 30, 1990 2:02 pm PDT
DIRECTORY
CrRPC USING [Handle],
IO USING [STREAM],
PFS USING [RopeFromPath, FileType, InfoProc, Mutability, nullUniqueID, tUnspecified, UniqueID],
PFSBackdoor USING [ProduceError],
PFSClass USING [AttachProc, CloseProc, CopyProc, DeleteProc, EnumerateClientPropertiesProc, EnumerateForInfoProc, EnumerateForNamesProc, FileInfoProc, FileManipulationProcs, FileManipulationProcsObject, FSHandle, FSObject, GetClientPropertyProc, GetHandleProc, GetInfoProc, LookupNameProc, MaintenanceProcs, MaintenanceProcsObject, OpenFile, OpenFileObject, OpenProc, ReadProc, Register, RenameProc, RetrieveProc, SetAttributesProc, SetByteCountAndUniqueIDProc, SetClientPropertyProc, StoreProc, SweepProc, ValidateProc, WriteProc],
PFSNames USING [Component, PATH, ShortName, Version],
Rope USING [ROPE],
XNSFilingFileMgr USING [CloseFileOp, OpenFile, OpenFileOp, ReadFileOp, WriteFileOp],
XNSFilingOps USING [CallProtected, EnumProc, EnumerateOp],
XNSFilingPrivate USING [DebugOut],
XNSFilingSession USING [ServerHandle, XNSGetServer, XNSSweep, XNSValidate];
XNSFilingViewImpl: CEDAR MONITOR LOCKS tr USING tr: Transport
IMPORTS PFS, PFSBackdoor, PFSClass, PFSNames, XNSFilingFileMgr, XNSFilingOps, XNSFilingPrivate, XNSFilingSession ~ {
OPEN XNSFilingFileMgr, XNSFilingOps, XNSFilingSession;
ROPE: TYPE ~ Rope.ROPE;
PFS Class name
xnsFlavor: ATOM ~ $XNS;
Maintenance Object
mo: PFSClass.MaintenanceProcs ~
NEW [PFSClass.MaintenanceProcsObject ← [
sweep: Sweep,
validate: Validate
]];
File Manipulation Object
fmo: PFSClass.FileManipulationProcs ~
NEW[PFSClass.FileManipulationProcsObject ← [
delete: Delete,
enumerateForInfo: EnumerateForInfo,
enumerateForNames: EnumerateForNames,
fileInfo: FileInfo,
lookupName: Lookup,
rename: Rename,
copy: Copy,
setAttributes: SetAttributes,
setByteCountAndUniqueID: SetByteCountAndUniqueID,
setClientProperty: SetClientProperty,
getClientProperty: GetClientProperty,
enumerateClientProperties: EnumerateClientProperties,
read: Read,
write: Write,
open: Open,
close: Close,
store: Store,
retrieve: Retrieve,
attach: Attach,
getInfo: GetInfo
]];
Initialized Data - order is important!
vfsClass: PFSClass.FSHandle ~ NEW [PFSClass.FSObject ← [
flavor: xnsFlavor,
name: NIL, -- filled in upon instantiation
maintenanceProcs: mo,
procs: fmo,
data: NIL -- filled in upon instantiation
]];
Transport Management
TransportProc: TYPE ~ PROC; -- [tr: Transport];
Transport: TYPE ~ REF TransportBody;
TransportBody: TYPE ~ MONITORED RECORD [
crH: CrRPC.Handle,
vfs: VFS
];
CallMonitored: PROC [vfs: VFS, inner: TransportProc] ~ {
crH: CrRPC.Handle ~ NIL;
link: Transport ~ NEW[TransportBody ← [crH, vfs]];
UnderLock: --ENTRY-- TransportProc ~ {
ENABLE UNWIND => { NULL };
inner[];
};
UnderLock[link];
CallProtected[vfs.sH.mnt, inner];
};
XNS Virtual File System(s)
VFS: TYPE ~ REF VFSInstance;
VFSInstance: TYPE ~ RECORD [
fs: ROPE,
flavorSpecified: BOOL,
sH: ServerHandle
];
GetHandle: PFSClass.GetHandleProc ~ {
vfs: VFS ~ NEW[VFSInstance ← [fs: fs, flavorSpecified: flavorSpecified, sH: NIL] ];
{
Attempt to Attach new vfs[h]
sH: ServerHandle; downMsg ← NIL;
[sH, downMsg] ← XNSGetServer[fs];
vfs.sH ← sH;
};
h ← NEW[PFSClass.FSObject ← vfsClass^];
h.name ← fs;
h.data ← vfs;
};
Maintenance Operations
Sweep: PFSClass.SweepProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
sH: ServerHandle ~ vfs.sH;
XNSSweep[sH, seconds];
NULL;
};
Validate: PFSClass.ValidateProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
sH: ServerHandle ~ vfs.sH;
obsolete ← FALSE; downMsg ← NIL;
[obsolete, downMsg] ← XNSValidate[sH];
IF ( FALSE ) THEN { obsolete ← TRUE; downMsg ← NIL };
IF ( FALSE ) THEN { obsolete ← FALSE; downMsg ← "downMsg" };
};
File Manipulation Procs
EnumerateForInfo: PFSClass.EnumerateForInfoProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
pat: ROPE ~ PFS.RopeFromPath[pattern];
EnumerateForInfoInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
Lister: EnumProc ~ {
eFile: PFSNames.PATH, eInfo: Info, pathy: PFSNames.PATH
fullFName: PFSNames.PATH ← pathy;
attachedTo: PFSNames.PATHNIL;
uniqueID: PFS.UniqueID ← [[time: eInfo.created]];
bytes: INT ← eInfo.bytes;
mutability: PFS.Mutability ← $immutable; -- policy decision!
fileType: PFS.FileType ← [eInfo.fileType]; -- identical type defs?
continue ← IF ( proc = NIL ) THEN TRUE ELSE
proc[fullFName, attachedTo, uniqueID, bytes, mutability, fileType];
};
createdOn: CARD32 ~ BasicTime.ToNSTime[wantedUniqueID.egmt.time];
EnumerateOp[vfs.sH.mnt, pattern, Lister, $enumerate];
};
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.EnumerateForInfo"];
XNSFilingPrivate.DebugOut[PFS.RopeFromPath[pattern]];
CallMonitored[vfs, EnumerateForInfoInner];
};
EnumerateForNames: PFSClass.EnumerateForNamesProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
Info: PFS.InfoProc ~ {
name: PFSNames.PATH ~ fullFName;
continue ← IF ( proc = NIL ) THEN TRUE ELSE proc[name];
};
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.EnumerateForNames"];
XNSFilingPrivate.DebugOut[PFS.RopeFromPath[pattern]];
EnumerateForInfo[h, pattern, Info, lbound, hbound];
EnumerateForNamesInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
UnImplemented["XNSFilingViewImpl.EnumerateForNamesInner"];
};
CallMonitored[vfs, EnumerateForNamesInner];
};
FileInfo: PFSClass.FileInfoProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
pattern: PFSNames.PATH ~ file;
zversion: PFSNames.Version ← [none];
zattachedTo: PFSNames.PATHNIL;
zuniqueID: PFS.UniqueID ← PFS.nullUniqueID;
zbytes: INT ← 0;
zmutability: PFS.Mutability ← $immutable;
zfileType: PFS.FileType ← PFS.tUnspecified;
Info: PFS.InfoProc ~ {
shortName: PFSNames.Component ~ PFSNames.ShortName[fullFName];
SELECT TRUE FROM
( wantedUniqueID = PFS.nullUniqueID ) => {
perhaps we should be checking for the *best* match?
continue ← TRUE;
};
( uniqueID = wantedUniqueID ) => { continue ← FALSE };
ENDCASE => { RETURN };
zversion ← shortName.version;
zattachedTo ← attachedTo;
zbytes ← bytes;
zuniqueID ← uniqueID;
zmutability ← mutability;
zfileType ← fileType;
};
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.FileInfo"];
XNSFilingPrivate.DebugOut[PFS.RopeFromPath[pattern]];
EnumerateForInfo[h, pattern, Info, NIL, NIL];
RETURN[zversion, zattachedTo, zbytes, zuniqueID, zmutability, zfileType];
FileInfoInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
UnImplemented["XNSFilingViewImpl.FileInfoInner"];
};
CallMonitored[vfs, FileInfoInner];
};
GetInfo: PFSClass.GetInfoProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.GetInfo"];
Generic Implementation
fullFName ← file.fullFName;
attachedTo ← file.attachedTo;
uniqueID ← file.uniqueID;
bytes ← file.bytes;
mutability ← file.mutability;
fileType ← file.fileType;
GetInfoInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
UnImplemented["XNSFilingViewImpl.GetInfoInner"];
};
CallMonitored[vfs, GetInfoInner];
};
File Operations
Read: PFSClass.ReadProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
ReadInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
xnsFile: XNSFilingFileMgr.OpenFile ~ NARROW[file.data];
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.ReadInner"];
XNSFilingPrivate.DebugOut[PFS.RopeFromPath[file.fullFName]];
bytesRead ← ReadFileOp[vfs.sH.mnt, xnsFile, filePosition, nBytes, to];
};
bytesRead ← 0;
CallMonitored[vfs, ReadInner];
};
Write: PFSClass.WriteProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
WriteInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
xnsFile: XNSFilingFileMgr.OpenFile ~ NARROW[file.data];
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.WriteInner"];
XNSFilingPrivate.DebugOut[PFS.RopeFromPath[file.fullFName]];
bytesWritten ← WriteFileOp[vfs.sH.mnt, xnsFile, filePosition, nBytes, from];
};
bytesWritten ← 0;
CallMonitored[vfs, WriteInner];
};
Close: PFSClass.CloseProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
CloseInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
xnsFile: XNSFilingFileMgr.OpenFile ~ NARROW[file.data];
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.CloseInner"];
XNSFilingPrivate.DebugOut[PFS.RopeFromPath[file.fullFName]];
CloseFileOp[vfs.sH.mnt, xnsFile];
};
CallMonitored[vfs, CloseInner];
};
Open: PFSClass.OpenProc ~ {
file: PATH, wantedUniqueID: UniqueID, access: PFS.AccessOptions, checkFileType: BOOL, fileType: PFS.FileType, createOptions: PFS.CreateOptions
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
LegitimateMatch: PROC RETURNS [match: BOOL] ~ {
match ← TRUE;
};
version: PFSNames.Version;
attachedTo: PFSNames.PATH;
bytes: INT;
uniqueID: PFS.UniqueID;
mutability: PFS.Mutability;
zfileType: PFS.FileType;
of: PFSClass.OpenFile ← NIL;
OpenInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
fullFName: PFSNames.PATH ~ file;
fs: PFSClass.FSHandle ~ h;
xnsFile: XNSFilingFileMgr.OpenFile ~ OpenFileOp[vfs.sH.mnt, fullFName];
data: REF ~ xnsFile;
new: PFSClass.OpenFile ~ NEW[PFSClass.OpenFileObject ← [fs, fullFName, attachedTo, uniqueID, bytes, mutability, zfileType, $open, data]];
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.OpenInner"];
XNSFilingPrivate.DebugOut[PFS.RopeFromPath[fullFName]];
of ← new;
};
[version, attachedTo, bytes, uniqueID, mutability, zfileType] ←
FileInfo[h, file, wantedUniqueID];
IF ( NOT LegitimateMatch[] )
THEN {
PFSBackdoor.ProduceError[unknownFile, "XNSFilingViewImpl.OpenInner"];
RETURN[NIL]; -- not reached!
};
XNSFilingPrivate.DebugOut["XNSFilingViewImpl.Open"];
XNSFilingPrivate.DebugOut[PFS.RopeFromPath[file]];
CallMonitored[vfs, OpenInner];
RETURN[of];
};
Utilities
UnImplemented: PROC [msg: ROPE] ~ {
XNSFilingPrivate.DebugOut[msg];
PFSBackdoor.ProduceError[notImplemented, msg];
};
UnImplemented so far...
Delete: PFSClass.DeleteProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
DeleteInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
fullName: PFSNames.PATHNIL;
uniqueID: PFS.UniqueID ← PFS.nullUniqueID;
continue: BOOLIF ( proc = NIL ) THEN TRUE ELSE proc[fullName, uniqueID];
UnImplemented["XNSFilingViewImpl.DeleteInner"];
};
CallMonitored[vfs, DeleteInner];
};
Lookup: PFSClass.LookupNameProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
path: PFSNames.PATH;
LookupInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
path ← NIL;
UnImplemented["XNSFilingViewImpl.LookupInner"];
};
CallMonitored[vfs, LookupInner];
RETURN[path];
};
Rename: PFSClass.RenameProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
RenameInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
done ← TRUE;
UnImplemented["XNSFilingViewImpl.RenameInner"];
};
CallMonitored[vfs, RenameInner];
};
Copy: PFSClass.CopyProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
CopyInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
done ← TRUE;
UnImplemented["XNSFilingViewImpl.CopyInner"];
};
CallMonitored[vfs, CopyInner];
};
SetAttributes: PFSClass.SetAttributesProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
SetAttributesInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
NULL;
UnImplemented["XNSFilingViewImpl.SetAttributesInner"];
};
CallMonitored[vfs, SetAttributesInner];
};
SetByteCountAndUniqueID: PFSClass.SetByteCountAndUniqueIDProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
SetByteCountAndUniqueIDInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
NULL;
UnImplemented["XNSFilingViewImpl.SetByteCountAndUniqueIDInner"];
};
CallMonitored[vfs, SetByteCountAndUniqueIDInner];
};
SetClientProperty: PFSClass.SetClientPropertyProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
SetClientPropertyInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
NULL;
UnImplemented["XNSFilingViewImpl.SetClientPropertyInner"];
};
CallMonitored[vfs, SetClientPropertyInner];
};
GetClientProperty: PFSClass.GetClientPropertyProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
GetClientPropertyInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
propertyValue ← NIL;
UnImplemented["XNSFilingViewImpl.GetClientPropertyInner"];
};
CallMonitored[vfs, GetClientPropertyInner];
};
EnumerateClientProperties: PFSClass.EnumerateClientPropertiesProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
EnumerateClientPropertiesInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
propertyName: ROPE; propertyValue: ROPE;
continue: BOOLIF ( proc = NIL ) THEN TRUE ELSE proc[propertyName, propertyValue];
UnImplemented["XNSFilingViewImpl.EnumerateClientPropertiesInner"];
};
CallMonitored[vfs, EnumerateClientPropertiesInner];
};
Store: PFSClass.StoreProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
StoreInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
fullName: PFSNames.PATHNIL;
continue: BOOLIF ( proc = NIL ) THEN TRUE ELSE proc[fullName];
UnImplemented["XNSFilingViewImpl.StoreInner"];
};
CallMonitored[vfs, StoreInner];
};
Retrieve: PFSClass.RetrieveProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
RetrieveInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
fullFName: PFSNames.PATHNIL;
bytes: INT ← 0;
uniqueID: PFS.UniqueID ← PFS.nullUniqueID;
s: IO.STREAMIF ( proc = NIL ) THEN NIL ELSE proc[fullFName, bytes, uniqueID];
IF ( s = NIL ) THEN ERROR;
UnImplemented["XNSFilingViewImpl.RetrieveInner"];
};
CallMonitored[vfs, RetrieveInner];
};
Attach: PFSClass.AttachProc ~ {
class: PFSClass.FSHandle ~ h;
vfs: VFS ~ NARROW[class.data];
AttachInner: TransportProc ~ {
ENABLE UNWIND => { NULL };
toFName ← NIL;
UnImplemented["XNSFilingViewImpl.AttachInner"];
};
CallMonitored[vfs, AttachInner];
};
Init: PROC ~ {
PFSClass.Register[xnsFlavor, GetHandle];
PFSClass.ClearCachedServer["*-XNS"];
};
Init[];
}.