PFSRopeFileImpl.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, November 25, 1991 3:30 pm PST
Doug Wyatt, October 22, 1991 11:18 am PDT
DIRECTORY
Basics USING [RawBytes, UnsafeBlock],
IO USING [PutR1, RIS, Value],
PFS USING [AccessOptions, AttributeSource, Close, CreateOptions, defaultCreateOptions, Error, FileInfo, FileType, Mutability, NameFormat, nullUniqueID, Open, OpenFile, OpenFileObject, Read, RopeFromPath, UniqueID],
PFSNames USING [Equal, PATH],
Rope USING [Substr, ROPE],
RopeFile USING [ByteSequenceObject, CreateByteSequenceObject, DeactivateResult, FromByteSequenceObject],
TiogaFileIO USING [GetParts, Parts];
~
BEGIN
OPEN
PFS;
PATH: TYPE ~ PFSNames.PATH;
ROPE: TYPE ~ Rope.ROPE;
ByteSequenceObject: TYPE ~ RopeFile.ByteSequenceObject;
DeactivateResult: TYPE ~ RopeFile.DeactivateResult;
Data: TYPE ~ REF DataRep;
DataRep:
TYPE ~
RECORD [
fullFName: PATH,
uniqueID: UniqueID,
fileName: ROPE,
created: ROPE,
openFile: OpenFile
];
PFSDeactivate:
ENTRY
PROC [self: ByteSequenceObject, final:
BOOL]
RETURNS [result: DeactivateResult ¬ ok] ~ {
data: Data ~ NARROW[self.data];
openFile: OpenFile ¬ data.openFile;
IF openFile = NIL THEN RETURN [alreadyInactive];
data.openFile ¬ NIL;
PFS.Close[openFile ! PFS.Error => { result ¬ cant } ];
};
PFSEqual:
ENTRY
PROC [self, other: ByteSequenceObject]
RETURNS [
BOOL] ~ {
data: Data ~ NARROW[self.data];
WITH other.data
SELECT
FROM
otherData: Data => {
IF self.length # other.length THEN RETURN [FALSE];
IF data.uniqueID # otherData.uniqueID THEN RETURN [FALSE];
IF
NOT PFSNames.Equal[data.fullFName, otherData.fullFName]
THEN
RETURN [
FALSE];
Note this is a case-insensitive compare; however we've already matched length and uniqueID, so the case-insensitivity shouldn't be problem.
RETURN [TRUE]
};
ENDCASE;
RETURN [FALSE]
};
PFSDescribe:
ENTRY
PROC [self: ByteSequenceObject]
RETURNS [fileName:
ROPE, created:
ROPE, open:
BOOL] ~ {
data: Data ~ NARROW[self.data];
RETURN [fileName: data.fileName, created: data.created, open: data.openFile#NIL];
};
PFSMove:
ENTRY
UNSAFE
PROC [self: ByteSequenceObject, block: Basics.UnsafeBlock, start:
INT]
RETURNS [charsMoved:
INT ¬ 0] ~
UNCHECKED {
ENABLE UNWIND => NULL;
FIXTHIS Turn PFS.Error into RopeFile.Error
data: Data ~ NARROW[self.data];
IF data.openFile =
NIL
THEN {
data.openFile ¬ PFS.Open[name: data.fullFName, wantedUniqueID: data.uniqueID];
};
charsMoved ¬ PFS.Read[file: data.openFile, filePosition: start, nBytes: block.count,
to: block.base, toStart: block.startIndex];
};
RopeOpen:
PUBLIC
PROC [fileName: PFSNames.
PATH, wantedUniqueID: UniqueID ¬ nullUniqueID, includeFormatting:
BOOL ¬
FALSE, checkMutability:
BOOL ¬
TRUE]
RETURNS [rope:
ROPE, fullFName:
PATH, uniqueID: UniqueID] ~ {
length: INT;
mutability: Mutability;
data: Data ~ NEW[DataRep];
[fullFName: fullFName, attachedTo: data.fullFName, uniqueID: uniqueID, bytes: length, mutability: mutability] ¬ FileInfo[fileName, wantedUniqueID];
data.uniqueID ¬ uniqueID;
IF data.fullFName = NIL THEN data.fullFName ¬ fullFName;
data.fileName ¬ RopeFromPath[fullFName];
data.created ¬ IO.PutR1[[time[uniqueID.egmt.gmt]]];
rope ¬ RopeFile.FromByteSequenceObject[byteSequenceObject: RopeFile.CreateByteSequenceObject[length: length, data: data, equal: PFSEqual, deactivate: PFSDeactivate, describe: PFSDescribe, move: PFSMove], flatten: checkMutability AND mutability=mutable];
IF
NOT includeFormatting
THEN {
parts: TiogaFileIO.Parts ~ TiogaFileIO.GetParts[IO.RIS[rope]];
IF parts.isTioga THEN rope ¬ Rope.Substr[rope, parts.start1, parts.len1];
};
};