FSPropertiesImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Schroeder, November 15, 1983 1:36 pm
Levin, September 22, 1983 1:04 pm
Bob Hagmann February 4, 1985 10:35:57 am PST
Russ Atkinson (RRA) May 13, 1985 9:08:19 pm PDT
DIRECTORY
BasicTime USING [GMT, nullGMT],
File USING [Error, FP, GetProperties, Handle, PageCount, PropertyStorage, RC, WriteProperties],
FSBackdoor USING [ProduceError, Version],
FSFileOps,
FSReport USING [FileError],
GVBasics USING [MakeKey, Password],
PrincOpsUtils USING [LongCopy],
Rope USING [Length, NewText, ROPE, Text];
FSPropertiesImpl: CEDAR MONITOR
IMPORTS File, FSBackdoor, FSReport, GVBasics, PrincOpsUtils, Rope
EXPORTS FSFileOps
= {
PropertiesObject: TYPE = RECORD [
validation: GVBasics.Password,
bytes: INT,
keep: CARDINAL,
created: BasicTime.GMT,
version: FSBackdoor.Version,
nameBody: TextRep];
TextRep: TYPE = RECORD[PACKED SEQUENCE length: CARDINAL OF CHAR];
Properties: TYPE = LONG POINTER TO PropertiesObject;
Exported to FSFileOps
GetProps: PUBLIC PROC [f: File.Handle] RETURNS [bytes: INT, keep: CARDINAL, created: BasicTime.GMT] = {
InnerGet: ENTRY PROC = TRUSTED {
ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties];
IF pPtr.validation = validation
THEN {
bytes ← pPtr.bytes;
keep ← pPtr.keep;
created ← pPtr.created;
}
ELSE invalidPP ← TRUE; -- invalid property page
};
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerGet[ ! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN InvalidPropertyPage[];
IF fileRC # ok THEN FSReport.FileError[fileRC];
};
GetNameBodyAndVersion: PUBLIC PROC [f: File.Handle] RETURNS [nameBody: Rope.Text, version: FSBackdoor.Version] = {
InnerGetNameBodyAndVersion: ENTRY PROC = TRUSTED {
ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties];
IF pPtr.validation = validation
THEN {
nameBody ← GetText[@pPtr.nameBody];
version ← pPtr.version;
}
ELSE invalidPP ← TRUE; -- invalid property page
};
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerGetNameBodyAndVersion[
! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN InvalidPropertyPage[];
IF fileRC # ok THEN FSReport.FileError[fileRC];
};
InitializePropertyStorage: PUBLIC PROC [fp: File.FP, propStorage: File.PropertyStorage, nPages: File.PageCount] = TRUSTED {
LOOPHOLE[propStorage, Properties].validation ← validation
};
SetProps: PUBLIC PROC [f: File.Handle, bytes: INT, keep: CARDINAL, created: BasicTime.GMT, nameBody: Rope.Text, version: FSBackdoor.Version] = {
InnerSet: ENTRY PROC = TRUSTED {
ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties];
IF pPtr.validation = validation
THEN {
IF bytes # -1 THEN pPtr.bytes ← bytes;
pPtr.keep ← keep;
IF created # BasicTime.nullGMT THEN pPtr.created ← created;
pPtr.version ← version;
PutText[nameBody, @(pPtr.nameBody)];
File.WriteProperties[f];
}
ELSE invalidPP ← TRUE; -- invalid property page here is a bug
};
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerSet[ ! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN ERROR;
IF fileRC # ok THEN FSReport.FileError[fileRC];
};
SetBytesAndCreated: PUBLIC PROC [f: File.Handle, bytes: INT, created: BasicTime.GMT] = {
InnerSetBytesAndCreated: ENTRY PROC = TRUSTED {
ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties];
IF pPtr.validation = validation
THEN {
IF bytes # -1 THEN pPtr.bytes ← bytes;
IF created # BasicTime.nullGMT THEN pPtr.created ← created;
File.WriteProperties[f];
}
ELSE invalidPP ← TRUE; -- invalid property page
};
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerSetBytesAndCreated[ ! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN InvalidPropertyPage[];
IF fileRC # ok THEN FSReport.FileError[fileRC];
};
SetKeep: PUBLIC PROC [f: File.Handle, keep: CARDINAL] = {
InnerSetKeep: ENTRY PROC = TRUSTED {
ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties];
IF pPtr.validation = validation
THEN {
pPtr.keep ← keep;
File.WriteProperties[f];
}
ELSE invalidPP ← TRUE; -- invalid property page
};
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerSetKeep[ ! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN InvalidPropertyPage[];
IF fileRC # ok THEN FSReport.FileError[fileRC];
};
Internal procedures
InvalidPropertyPage: PROC = {
FSBackdoor.ProduceError[invalidPropertyPage, "Property page of a local file has a bad property page"];
};
GetText: PROC [tR: LONG POINTER TO TextRep] RETURNS [t: Rope.Text] = TRUSTED {
chars: NAT ← tR.length;
IF chars = 0
THEN t ← NIL
ELSE {
t ← Rope.NewText[chars];
PrincOpsUtils.LongCopy[
from: tR + SIZE[TextRep[0]],
nwords: SIZE[TEXT[chars]] - SIZE[TEXT[0]],
to: LOOPHOLE[t, LONG POINTER] + SIZE[TEXT[0]]
];
};
};
PutText: PROC [t: Rope.Text, tR: LONG POINTER TO TextRep] = TRUSTED {
chars: NAT ← Rope.Length[t];
bogus: LONG POINTER TO NATLOOPHOLE[tR];
bogus^ ← chars;
We would rather do "tR.length ← chars", but the compiler won't allow it.
IF chars # 0 THEN
PrincOpsUtils.LongCopy[
to: tR + SIZE[TextRep[0]],
nwords: SIZE[TEXT[chars]] - SIZE[TEXT[0]],
from: LOOPHOLE[t, LONG POINTER] + SIZE[TEXT[0]]
];
};
validation: GVBasics.Password ← ALL[0];
ComputeValidation: PROC = {
Validation stuff for leader pages; changing the stamp will require all nucleus volumes to be erased.
stamp: Rope.ROPE = "August 19, 1983 1:16 pm"; -- DON'T CHANGE THIS!!! --
validation ← GVBasics.MakeKey[stamp];
};
Start code.
ComputeValidation[];
}.
Bob Hagmann February 4, 1985 9:45:28 am PST
changes for exending property storage in File, added Copyright
changes to: DIRECTORY, GetProps, GetNameBodyAndVersion, InitializePropertyStorage, SetProps, SetBytesAndCreated, SetKeep, GetProps, GetNameBodyAndVersion, InitializePropertyStorage, SetProps, SetBytesAndCreated, SetKeep