PSExecEImpl.mesa
Copyright (C) Xerox Corporation 1985. All rights reserved.
Last edited by Jacks 13-Dec-85 16:47:12
Ruseli Binsol: December 16, 1986 1:51:25 pm PST
Implements InstallFromFloppy command for PS exec interface.
This module is really hard to understand, especially the code for loading multi-floppy fonts using the script file. In the future we will probably want to try and make use of the SCS code for manipulating files or something. Alot of InstallFromFloppy seem like one big kludge to me. **A. Jacks 5/30/84
All modules referencing AccessFloppy, AccessFloppyUtil, Floppy, FloppyChannel, and NSDataStream are commented out because there is currently no implementation to support these. **RBinsol 12/15/86
DIRECTORY
AccessFloppy USING [Attributes, AttributesRecord, Close, Error, ErrorType, GetAttributes, leaderLength, LookUp, maxDataSize, maxNameLength, Open],
AccessFloppyUtil USING [CreateBuffer, DeleteBuffer, MesaStringFromAttributes],
BasicTime USING [GMT],
File USING [PageCount, PageNumber],
Floppy USING [DataError, Error, ErrorType, FileHandle, GetAttributes, GetNextFile, maxCharactersInLabel, nullFileID, nullVolumeHandle, PageNumber, Read, VolumeHandle],
FloppyChannel USING [Error, GetHandle, Nop],
IO USING [PutBlock],
NSDataStream USING [Abort, Aborted, SinkStream],
NSExec USING [Error, ClientID, ExecProc, GetTTY, Handle, OutputHandle],
NSString USING [AppendString, EqualStrings, FreeString, nullString, String, StringRep],
PrincOps USING [BYTE],
Process USING [MsecToTicks, Pause],
PSAssignedTypes USING [tFont200Rotated90, tFont300Rotated0, tFont300Rotated90],
PSCommand USING [DeleteFont, Error, FileProc, FontProc, GetPrintServiceStatus],
PSExec USING [GetClientID],
PSExecInternal USING [ExpandKeyAndPrint],
PSExecMessages USING [Key],
PSKMessages USING [GetHandle],
PSState USING [StateHandle],
RefText USING [Map],
TestPattern USING [alignment, bansheeAlignment, darkDusting, greyDusting, Name, NotFound],
TextInput USING [GetYesNo, nilYesNo, YesOrNo],
TTY USING [Handle, Rubout],
VM USING [Interval, nullInterval, PageCount],
Volume USING [ID, InsufficientSpace],
XFormat USING [Blanks, CR, Date, Handle, NSStringObject],
XMessage USING [Get, Handle, Compose, StringArray];
XString USING [ReaderBody];
PSExecEImpl: CEDAR PROGRAM
IMPORTS NSExec, NSString, PSCommand, PSExec, PSExecInternal, PSKMessages, TextInput, TTY, XFormat, XMessage
EXPORTS PSExecInternal
SHARES NSString = BEGIN
psClientID: NSExec.ClientID ← PSExec.GetClientID[];
Used for displaying dates from stored files and files on floppies:
nsDateAndTime: NSString.String ← NEW[TEXT[40]];
nsDateTimeObject: XFormat.Handle ← XFormat.NSStringObject[nsDateAndTime];
Message domain handle:
execMsgs: XMessage.Handle ← PSKMessages.GetHandle[exec];
=========================================
COMMAND PROCESSING ROUTINE
=========================================
===============================================
InstallFromFloppy: PUBLIC NSExec.ExecProc =
===============================================
This is a very complex routine (a kludge!). There are really two modes in which it runs: normal and script mode. Normal mode is for installing floppy files which fit on a single floppy. Files which are installed from more than one floppy use script mode. The main procedure is Install.
NORMAL MODE: In normal mode, the procedure Install reads and displays the names and certain attributes of the files on the floppy one by one. A call is made to LoadConfirmation for each file and the operator is asked to confirm whether or not the file should be installed. If so, a call is made to PSCommand.InstallFont or PSCommand.InstallFile (for test patterns), passing as a parameter the procedure SendFloppyData. The PSCommand implementation takes care of creating a data stream and calls SendFloppyData which puts the floppy data, block by block, on the sink stream.
SCRIPT MODE: There is a script file on every floppy for multi-floppy files, which follows a certain language for specifying the pieces of the file being installed. If the procedure Install, while reading the names and attributes of the files on the floppy, comes across a "piece" file (a file not contained completely on one floppy) it calls EnterScriptMode. EnterScriptMode calls BeginInterprete, which reads the script file into memory, sets up the state record data and begins executing the script. The procedure GetCommand parses the script and places the next command and it's parameter in the global variable "scriptCommand". Currently supported script commands are: Create File (parameter = file name), Request Volume (parameter = name of the floppy containing the next file piece), Load Piece (parameter = name of file piece to load) and Close File (parameter = file name). (The command Load All is specified but not currently supported.) BeginInterprete first looks for the command Create File and then calls CreateFileName which justs records the file name in the state record as "state.nameDest". BeginInterprete next looks for the command Load Piece and then calls SetPieceFileContext before returning to EnterScriptMode. BeginInterprete calls SetPieceFileContext, even though that is done in the LoadPiece procedure anyway, because we need the create date of the file for the call to PSCommand.InstallFont. EnterScriptMode makes the call to PSCommand.InstallFont passing as a parameter the procedure InterpreteScript. The PSCommand implementation takes care of setting up the data stream and calls InterpreteScript to get the data. InterpreteScript first calls LoadPiece to execute the command already found by BeginInterprete. Then it enters a loop and interpretes the script file by calling GetCommand and then calling the appropriate procedure to carry out the command. Usually it calls RequestVolume, which prompt the operator to insert the next floppy, and then LoadPiece for each floppy until the font is completely installed. LoadPiece calls SendFloppyData, which actually puts the floppy data block by block on the data sink. At the end of the script file AnnounceEndOfData is called. Or, if an error is encountered, AbortInstall is called. Execution eventually falls back to the Install procedure and installation is complete.
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
tty: TTY.Handle ← NSExec.GetTTY[exec];
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
UserAbort: ERROR = CODE;
SendDataError: ERROR = CODE;
Answer: TYPE = {no, yes, cancel}; -- no: skip and go to next, yes: do it, cancel: abort it.
CommandType: TYPE = {
nullcommand, closeFile, createFile, loadAll, loadPiece, requestVolume};
Command: TYPE = REF CommandRecord;
CommandRecord: TYPE = RECORD [
type: CommandType ← nullcommand, parameter: NSString.String ← NIL];
floppyHandle: Floppy.VolumeHandle ← Floppy.nullVolumeHandle; -- floppy volume handle.
nullFloppyFileHandle: Floppy.FileHandle ← [
Floppy.nullVolumeHandle, Floppy.nullFileID];
null floppy file handle, should be updated when a floppy is opened or closed.
DataType: TYPE = {font, testPattern};
FloppyFileContext: TYPE = LONG POINTER TO FloppyFileContextRecord;
FloppyFileContextRecord: TYPE = RECORD [
id: Floppy.FileHandle ← nullFloppyFileHandle, -- File handle on floppy
attributes: AccessFloppy.Attributes ← NIL, -- Floppy File Attributes
fileName: LONG STRINGNIL,
nsFileName: NSString.String ← NSString.nullString,
File names indicate destination file in case of multi-floppy fonts and, thus, may not be the name of the file with the given id.
dataType: DataType ← font];
State: TYPE = REF StateRecord;
StateRecord: TYPE = RECORD [
nameDest: NSString.String ← NSString.nullString,
nameDest: LONG STRINGNIL,
sizeDest: File.PageCount ← 0, -- target file size
sizeMapped: File.PageCount ← 0, -- actual size, use to check consistency of the destination file.
create: BOOLEANFALSE, -- set by Create File
close: BOOLEANFALSE, -- set by CloseFile, AnounceEndOfData.
version: Version ← new, -- *MT in case of Error for multi-floppies.
length: CARDINAL ← 0, -- number of source file pieces
piece: SEQUENCE maxlength: [0..LAST[CARDINAL]) OF FilePiece];
FilePiece: TYPE = RECORD [
vol: NSString.String ← NIL, base: File.PageNumber ← [0], size: File.PageCount ← 0];
Version: TYPE = {new, newer, same, older};
scriptName: NSString.String = "FontScript.";
nullSinkStream: NSDataStream.SinkStream = [[NIL]];
GLOBAL VARIABLES:
floppyFile: FloppyFileContextRecord ← [];
attributes: AccessFloppy.Attributes ← NIL;
This attributes is used by all floppy file (except script file). Storage is created when confirmation is made to load a floppy first time and the space is freed before exits from LoadFileFromFloppy.
labelString: LONG STRING ← [Floppy.maxCharactersInLabel]; -- floppy label string
nFontsInstalled: CARDINAL ← 0; -- total number of fonts installed.
nTestPatternsInstalled: CARDINAL ← 0; -- total number of test patterns installed.
Used during script interpretation:
state: State ← NIL;
scriptFile: FloppyFileContext ← NIL;
Remember the file context of the script file.
scriptPointer: LONG POINTERNIL;
Points to script file in VM.
scriptBuffer: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTERNIL;
For reading characters from script file.
scriptBytesRead: LONG CARDINAL ← 0;
scriptOffset: CARDINAL ← 0; -- Next char to read from script file.
scriptCommand: Command ← NIL; --Points to command just read from script file.
scriptInterpretationMode: BOOLEANFALSE; -- Whether it is in the script - interpretation mode.
firstPieceFile: BOOLEANFALSE; --Whether piece file is first one for given font.
waitChange: CARDINAL ← 3000; -- m sec. to wait for change floppy
systemAbort: BOOLEANFALSE; --Set to true in SendFloppyData if data stream is aborted by receiver; referenced in LoadPiece.
Variables used by mainline code of InstallFromFloppy
continue: TextInput.YesOrNo ← TextInput.nilYesNo;
psState: PSState.StateHandle ← PSCommand.GetPrintServiceStatus[];
Procedures for Processing Script
AbortInstall: PROCEDURE [displayMsg: BOOLEANTRUE, dataSink: NSDataStream.SinkStream ← nullSinkStream] RETURNS [NSDataStream.SinkStream] = BEGIN
IF ~state.close THEN BEGIN
state.close ← TRUE;
IF displayMsg THEN BEGIN
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyCanceled]];
END;
IF dataSink # nullSinkStream THEN BEGIN
NSDataStream.Abort[dataSink ! NSDataStream.Aborted => CONTINUE];
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
END;
END;
RETURN [nullSinkStream];
END; -- AbortInstall
AnnounceEndOfData: PROCEDURE [dataSink: NSDataStream.SinkStream] RETURNS [NSDataStream.SinkStream] = BEGIN
IF ~state.close THEN BEGIN
state.close ← TRUE;
IF dataSink # nullSinkStream THEN
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
END;
RETURN [nullSinkStream];
END; -- AnnounceEndOfData
BeginInterprete: PROCEDURE RETURNS [ok: BOOLEAN] = BEGIN -- Read Script File... map script file into VM
endOfScript: BOOLEANFALSE;
ok ← TRUE;
systemAbort ← FALSE; --global var
scriptPointer ← Space.ScratchMap[scriptFile.attributes.totalSize];
Floppy.Read[scriptFile.id, AccessFloppy.leaderLength,
scriptFile.attributes.totalSize, scriptPointer !
Floppy.Error, Floppy.DataError => {
scriptPointer ← Space.Unmap[scriptPointer]; REJECT}];
scriptBuffer ← scriptPointer;
STATE.CREATE AND STATE.CLOSE:
Initial state: state.create = FALSE, state.close = FALSE.
After LoadPiece has been called to send first floopy's data: state.create = TRUE, state.close = FALSE.
After CloseFile or AnnounceEndOfData is called: state.create = TRUE, state.close = TRUE: This initial state causes NOP.
After EndInterprete has been executed: state.create = FALSE, state.close = TRUE.
state ← NEW[StateRecord[30--10--]]; --*MT
state.nameDest ← NIL;
state.sizeDest ← 0;
state.sizeMapped ← 0;
state.create ← FALSE;
state.close ← FALSE;
state.length ← 0;
Allocate buffer for storing 30 (← 10 *MT) file - piece information.
scriptInterpretationMode ← TRUE;
scriptBytesRead ← 0;
scriptOffset ← 0;
scriptCommand ← NEW[CommandRecord];
scriptCommand.parameter ← NSString.MakeString[AccessFloppy.maxNameLength];
[endOfScript,] ← GetCommand[];
UNTIL endOfScript OR ~ok DO
SELECT scriptCommand.type FROM
createFile => {
ok ← CreateFileName[scriptCommand.parameter]; EXIT};
requestVolume =>
ok ← RequestVolume[scriptCommand.parameter,];
ENDCASE => GOTO Exit;
[endOfScript,] ← GetCommand[];
ENDLOOP;
IF NOT endOfScript AND ok THEN
[endOfScript,] ← GetCommand[];
UNTIL endOfScript OR ~ok DO
SELECT scriptCommand.type FROM
loadPiece => {
ok ← SetPieceFileContext[scriptCommand.parameter,];
firstPieceFile ← TRUE; EXIT};
requestVolume =>
ok ← RequestVolume[scriptCommand.parameter,];
ENDCASE => GOTO Exit;
[endOfScript,] ← GetCommand[];
ENDLOOP;
IF endOfScript THEN GOTO Exit;
EXITS Exit => NULL;
EXITS Exit => {[] ← AbortInstall[]; RETURN [ok ← FALSE]};
END; -- BeginInterprete.
CheckInstalledFont: PSCommand.FontProc = BEGIN
[type, packageName, sizeInBytes, createDate] RETURNS [continue]--
retries: CARDINAL ← 0;
sizeInPages: LONG CARDINAL
(sizeInBytes + PrincOps.bytesPerPage - 1)/PrincOps.bytesPerPage;
IF (state.sizeDest > state.sizeMapped OR state.sizeDest > sizeInPages)
AND state.version # same THEN --ignore the overwritten part if file is the same??
PSCommand.DeleteFont[packageName
! PSCommand.Error => WITH problem SELECT FROM
disallowedInCurrentMode => IF retries = 3
THEN {nFontsInstalled ← nFontsInstalled + 1; CONTINUE}
ELSE {retries ← retries + 1; RETRY};
ENDCASE
]
ELSE nFontsInstalled ← nFontsInstalled + 1;
RETURN [FALSE];
END; --CheckInstalledFont
EnterScriptMode: PROCEDURE = BEGIN
continue: BOOLEANTRUE;
fontPackageName: NSString.String ← NSString.nullString;
BEGIN ENABLE UNWIND =>
{IF fontPackageName # NSString.nullString THEN
PSCommand.DeleteFont[fontPackageName !PSCommand.Error => CONTINUE];
FreeGlobalSpace[]};
scriptFile ← NEW[FloppyFileContextRecord];
attributes recored of script floppy file.
scriptFile.attributes ← NEW[
AccessFloppy.AttributesRecord[AccessFloppy.maxDataSize]];
scriptFile.nsFileName ← Str[scriptName];
scriptFile.id ← AccessFloppy.LookUp[
scriptFile.nsFileName, scriptFile.attributes];
AccessFloppy.GetAttributes[scriptFile.id, scriptFile.attributes];
IF IsPieceFile[scriptFile.attributes] THEN {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyIncompleteScript]];
RETURN};
scriptFile.fileName ← scriptName;
Enter Script-interpretation Mode...
continue ← BeginInterprete[];
IF continue AND state.nameDest # NIL THEN BEGIN
fontPackageName ← Str[state.nameDest];
PSCommand.InstallFont[
type: cdFont,
packageName: fontPackageName,
createDate: floppyFile.attributes.createDate,
data: [proc[InterpreteScript]],
packageSizeHintInBytes: floppyFile.attributes.totalSizeInBytes
! PSCommand.Error => {
WITH p: problem SELECT FROM
abortedByClient => NULL;
insufficientSpace => {
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyErrInsufficientVolSpace], 2];
outputHandle.NSLine[M[mFloppyCanceled]]};
disallowedInCurrentMode => BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← XMessage.Compose[M[mConflictingMode], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
END;
documentInProgress => BEGIN
We CAN get here since, with the advent of remote administration,
two users may be logged at the same time. One could start printing
before the other finishes installing fonts.
stringArray: REF XMessage.StringArray ← NEW[XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
outputHandle.NSLine[M[mDocInProgress]];
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← XMessage.Compose[M[mPleaseStopPrinting], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
END;
ENDCASE => {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyCanceled]]};
CONTINUE}];
END;
Exit Script-interpretation Mode...
EndInterprete[fontPackageName];
END; --Enable Clause and code
END; --EnterScriptMode.
EndInterprete: PROCEDURE [fontPackageName: NSString.String] = BEGIN
IF state.create AND fontPackageName # NSString.nullString THEN
PSCommand.ListFonts[proc: CheckInstalledFont, filter: [packageName: fontPackageName]];
FreeGlobalSpace[];
scriptInterpretationMode ← FALSE;
END; -- EndInterprete.
FreeGlobalSpace: PROCEDURE = TRUSTED BEGIN
IF scriptPointer # NIL THEN
scriptPointer ← Space.Unmap[scriptPointer];
scriptBuffer ← NIL;
IF scriptCommand # NIL THEN BEGIN
IF scriptCommand.parameter # NIL THEN
NSString.FreeString[scriptCommand.parameter];
FREE[@scriptCommand];
END;
IF state # NIL THEN BEGIN
IF state.nameDest # NIL THEN NSString.FreeString[state.nameDest];
FOR i: CARDINAL IN [0..state.length) DO
IF state.piece[i].vol # NIL THEN
NSString.FreeString[state.piece[i].vol];
ENDLOOP;
FREE[@state];
END;
IF scriptFile # NIL THEN BEGIN
IF scriptFile.attributes # NIL THEN FREE[@scriptFile.attributes];
FREE[@scriptFile];
END;
END; --FreeGlobalSpace
GetCommand: PRIVATE PROCEDURE [dataSink: NSDataStream.SinkStream ← nullSinkStream] RETURNS [eof: BOOLEAN, returnDataSink: NSDataStream.SinkStream] = BEGIN
error: BOOLEANFALSE;
node1: NSString.String ← NEW[TEXT[8]];
node2: NSString.String ← NEW[TEXT[8]];
ReadChar: PROC RETURNS [newChar: CHARACTER, end: BOOLEAN] = BEGIN
end ← FALSE;
newChar ← scriptBuffer[scriptOffset];
scriptOffset ← scriptOffset + 1;
IF (scriptBytesRead ← scriptBytesRead + 1) = scriptFile.attributes.totalSizeInBytes THEN
end ← TRUE;
END; -- ReadChar
Token: PROC [string: LONG STRING, parameterToken: BOOLEANFALSE] = BEGIN
"parameterToken" indicates whether the token begin read in is a parameter (e.g. file name), rather than a command. IF so, a space does not indicate the end of the token and double quotes are regarded as token delimiters.
space: CHARACTER = 40C;
cr: CHARACTER = 15C;
semicolon: CHARACTER = 73C;
doubleQuote: CHARACTER = 42C;
i: CARDINAL ← 0;
newChar: CHARACTER ← 40C;
string.length ← 0;
skip delimiting characters
UNTIL eof DO
[newChar, eof] ← ReadChar[];
IF (newChar # cr) AND (newChar # semicolon) AND
(newChar # space) AND ((newChar # doubleQuote) OR NOT parameterToken) THEN
EXIT
ENDLOOP;
FOR i IN [0..string.maxlength) UNTIL eof DO
NSString.AppendCharacter[string, newChar];
[newChar, eof] ← ReadChar[];
IF (newChar # cr) AND (newChar # semicolon) AND
((newChar # space) OR parameterToken) AND
((newChar # doubleQuote) OR NOT parameterToken) THEN
LOOP
ELSE EXIT;
ENDLOOP;
END; --Token
eof ← FALSE;
Token[node1];
IF eof THEN RETURN [eof, dataSink];
Token[node2];
IF eof THEN RETURN [eof, dataSink];
Token[string: scriptCommand.parameter, parameterToken: TRUE]; --Spaces are allowed in file names.
SELECT TRUE FROM
NSString.EqualStrings[node1, "Load"] => {
SELECT TRUE FROM
NSString.EqualStrings[node2, "All"] => scriptCommand.type ← loadAll;
NSString.EqualStrings[node2, "Piece"] => scriptCommand.type ← loadPiece;
ENDCASE => error ← TRUE};
NSString.EqualStrings[node1, "Request"] =>
IF NSString.EqualStrings[node2, "Volume"] THEN
scriptCommand.type ← requestVolume
ELSE error ← TRUE;
NSString.EqualStrings[node1, "Create"] =>
IF NSString.EqualStrings[node2, "File"] THEN scriptCommand.type ← createFile
ELSE error ← TRUE;
NSString.EqualStrings[node1, "Close"L] =>
IF NSString.EqualStrings[node2, "File"] THEN scriptCommand.type ← closeFile
ELSE error ← TRUE;
ENDCASE => error ← TRUE;
IF error THEN {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyScriptError]];
dataSink ← AbortInstall[,dataSink];
eof ← error};
RETURN [eof, dataSink];
END; -- GetCommand
InterpreteScript: PROCEDURE [dataSink: NSDataStream.SinkStream] = BEGIN
ENABLE BEGIN
UNWIND => {
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];;
outputHandle.CR[];
stringArray[0] ← M[mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, stringArray];
outputHandle.CR[];
dataSink ← AbortInstall[,dataSink];
};
AccessFloppy.Error => { --NOTE: add error messages specific to AccessFloppy for next release.
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
outputHandle.CR[];
stringArray[0] ← M[
SELECT type FROM
volumeNotOpen => mFloppyErrVolumeNotOpen,
fileNotFound => mFloppyFileError, --NOTE: add a better message for next release
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, stringArray];
outputHandle.CR[];
IF type = volumeNotOpen THEN {
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID]};
GOTO Abort};
Floppy.Error => {
stringArray: ARRAY [0..1) OF NSString.String;
outputHandle.CR[];
stringArray[0] ← M[
SELECT error FROM
badDisk => mFloppyErrBadDisk,
badSectors => mFloppyErrBadSectors,
hardwareError => mFloppyErrHardware,
invalidVolumeHandle => mFloppyErrInvalidVolumeHandle,
needsScavenging => mFloppyErrNeedsScavenging,
noSuchDrive => mFloppyErrNoSuchDrive,
notReady => mFloppyErrNotReady,
stringTooShort => mFloppyErrStringTooShort,
volumeNotOpen => mFloppyErrVolumeNotOpen,
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, DESCRIPTOR[stringArray]];
outputHandle.CR[];
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID];
GOTO Abort};
END; --Enable Clause
end: BOOLEANFALSE;
ok: BOOLEANTRUE;
IF dataSink = nullSinkStream THEN RETURN;
[ok, dataSink] ← LoadPiece[scriptCommand.parameter, dataSink];
[end, dataSink] ← GetCommand[dataSink];
UNTIL end OR ~ok DO -- end = TRUE if end of file
SELECT scriptCommand.type FROM
loadPiece => [ok, dataSink] ← LoadPiece[scriptCommand.parameter, dataSink];
loadAll => [ok, dataSink] ← LoadAll[scriptCommand.parameter, dataSink]; --not implemented
closeFile => [ok, dataSink] ← CloseFile[scriptCommand.parameter, dataSink];
requestVolume => [ok, dataSink] ← RequestVolume[scriptCommand.parameter, dataSink];
ENDCASE => {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyScriptError]];
GOTO Abort};
[end, dataSink] ← GetCommand[dataSink];
ENDLOOP;
dataSink ← AnnounceEndOfData[dataSink];
EXITS Abort => dataSink ← AbortInstall[,dataSink];
END; -- InterpreteScript
SetPieceFileContext: PROCEDURE [str: NSString.String, dataSink: NSDataStream.SinkStream ← nullSinkStream] RETURNS [ok: BOOLEAN, returnDataSink: NSDataStream.SinkStream] = BEGIN
floppyFile ← [];
floppyFile.attributes ← attributes;
floppyFile.fileName ← str;
floppyFile.nsFileName ← Str[str];
floppyFile.id ← AccessFloppy.LookUp[
floppyFile.nsFileName, floppyFile.attributes];
IF ~IsPieceFile[floppyFile.attributes] THEN
BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← floppyFile.nsFileName;
outputHandle.CR[];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyNotFilePiece, stringArray];
dataSink ← AbortInstall[,dataSink];
RETURN [ok ← FALSE, dataSink];
END
ELSE RETURN [ok ← TRUE, dataSink];
END; --SetPieceFileContext
command interpreter.
CloseFile: PRIVATE PROCEDURE [str: NSString.String] RETURNS [ok: BOOLEAN] = BEGIN
ok ← NSString.EqualStrings[str, state.nameDest];
IF ok THEN dataSink ← AnnounceEndOfData[dataSink]
ELSE dataSink ← AbortInstall[dataSink];
RETURN [ok, dataSink];
END; -- CloseFile.
CreateFileName: PROCEDURE [str: NSString.String] RETURNS [ok: BOOLEAN] = BEGIN
ok ← TRUE;
state.nameDest ← NSString.MakeString[str.length];
NSString.AppendString[state.nameDest, str.length];
END; -- CreateFileName
LoadPiece will only load file piece.
LoadPiece: PRIVATE PROCEDURE [str: LONG STRING, dataSink: NSDataStream.SinkStream]
RETURNS [ok: BOOLEAN, returnDataSink: NSDataStream.SinkStream] = BEGIN
ok ← TRUE;
IF ~firstPieceFile THEN BEGIN
[ok, dataSink] ← SetPieceFileContext[str, dataSink];
IF ~ok THEN GOTO Exit;
END;
IF WindowOverlay[] THEN GOTO Exit;
UpdateSourceState[];
IF firstPieceFile THEN BEGIN
floppyFile.fileName ← state.nameDest;
floppyFile.nsFileName ← Str[state.nameDest];
File name now indicates name of destination file rather that floppy file.
SELECT LoadConfirmation[] FROM
no, cancel => {
dataSink ← AbortInstall[displayMsg: FALSE, dataSink: dataSink];
RETURN [ok ← FALSE, dataSink]};
ENDCASE;
END;
SendFloppyData[dataSink ! SendDataError =>
{dataSink ← nullSinkStream; GOTO Exit}];
IF systemAbort THEN RETURN [ok ← FALSE, dataSink ← nullSinkStream];
Stream was aborted by receiver. Error will be raised by PSCommand.InstallFont.
IF firstPieceFile THEN BEGIN
state.sizeDest ← floppyFile.attributes.totalSize;
state.create ← TRUE;
firstPieceFile ← FALSE;
END;
state.sizeMapped ← state.sizeMapped + floppyFile.attributes.size;
RETURN [ok, dataSink];
EXITS Exit => {dataSink ← AbortInstall[,dataSink];
RETURN [ok ← FALSE, dataSink]};
END; -- LoadPiece.
LoadAll: PRIVATE PROCEDURE [str: LONG STRING, dataSink: NSDataStream.SinkStream] RETURNS [ok: BOOLEAN, returnDataSink: NSDataStream.SinkStream] = BEGIN
This procedure implements the merge function of prepress file. This is used to merge multiple font files into a destinateion font file (created by Create File). Note: NOT font PIECES.
RETURN [ok ← TRUE, dataSink];
END; -- LoadAll.
RequestVolume: PRIVATE PROCEDURE [str: NSString.String] RETURNS [ok: BOOLEAN] = BEGIN
IF the requested volume is not online then request it, online, and save state otherwise RETURN.
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
maxRetry: CARDINAL = 3;
i: CARDINAL ← 0;
displayMsg: BOOLEANTRUE; --Indicates whether to display canceled msg on abort.
AwaitFloppyChange: PROC = BEGIN OPEN FloppyChannel;
^^^ Copied from PromOpsImpl.mesa if the floppy is ready, wait until it goes notReady first
UNTIL FloppyChannel.Nop[
FloppyChannel.GetHandle[0] !
FloppyChannel.Error => IF type = invalidHandle THEN RETRY] = notReady DO
Process.Pause[Process.MsecToTicks[waitChange]]; ENDLOOP;
UNTIL FloppyChannel.Nop[
FloppyChannel.GetHandle[0] !
FloppyChannel.Error => IF type = invalidHandle THEN RETRY] # notReady DO
Process.Pause[Process.MsecToTicks[waitChange]]; ENDLOOP;
END; -- of AwaitFloppyChange
IF ok ← NSString.EqualStrings[str, labelString] THEN RETURN [ok, dataSink] --##MT
ELSE OfflineFP0[];
FOR i IN [0..maxRetry) DO
outputHandle.CR[];
stringArray[0] ← Str[str];
PSExecInternal.ExpandKeyAndPrint[exec,
mFloppyPleaseRemoveAndInsert, stringArray];
AwaitFloppyChange[];
OpenVolume[labelString !
Floppy.Error => {
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
outputHandle.CR[];
stringArray[0] ← M[
SELECT error FROM
hardwareError => mFloppyErrHardware,
invalidVolumeHandle => mFloppyErrInvalidVolumeHandle,
needsScavenging => mFloppyErrNeedsScavenging,
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, stringArray];
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID];
EXIT};
UserAbort => {displayMsg ← FALSE; EXIT}
];
IF NSString.EqualStrings[str, labelString] THEN RETURN [TRUE, dataSink] ELSE OfflineFP0[];
ENDLOOP;
by here, failed!
dataSink ← AbortInstall[displayMsg, dataSink];
RETURN [ok ← FALSE, dataSink];
END; -- RequestVolume
UpdateSourceState: PROCEDURE = BEGIN
i: CARDINAL ← state.length;
state.piece[i].vol ← NSString.MakeString[labelString.maxlength];
NSString.CopyString[to: state.piece[i].vol, from: labelString];
state.piece[i].base ← floppyFile.attributes.offset;
state.piece[i].size ← floppyFile.attributes.size;
state.length ← i + 1;
END; -- UpdateSourceState
WindowOverlay: PROCEDURE RETURNS [overlay: BOOLEAN] = BEGIN
overlay ← FALSE;
FOR i: CARDINAL IN [0..state.length) UNTIL overlay DO
SELECT TRUE FROM
state.piece[i].base = floppyFile.attributes.offset => overlay ← TRUE;
state.piece[i].base < floppyFile.attributes.offset =>
IF state.piece[i].base + state.piece[i].size <=
floppyFile.attributes.offset THEN LOOP
ELSE overlay ← TRUE;
ENDCASE =>
IF floppyFile.attributes.offset + floppyFile.attributes.size
<= state.piece[i].base THEN LOOP
ELSE overlay ← TRUE;
ENDLOOP;
END; -- WindowOverlay
End of script processing procedures.
DisplayDates: PROCEDURE RETURNS [version: Version ← new] = BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
DisplayCurrentDate: PROCEDURE [createDate: BasicTime.GMT] = BEGIN
nsDateAndTime.length ← 0;
XFormat.Date[nsDateTimeObject, createDate]; --appends createDate to nsDataAndTime
stringArray[0] ← nsDateAndTime;
PSExecInternal.ExpandKeyAndPrint[exec, mRDFileCreated, stringArray];
version ←
SELECT TRUE FROM
(createDate < floppyFile.attributes.createDate) => newer,
(createDate = floppyFile.attributes.createDate) => same,
ENDCASE => older;
END; --DisplayCurrentDate
DisplayCurrentFontDate: PSCommand.FontProc = BEGIN
[type, packageName, sizeInBytes, createDate]--
RETURNS [continue ← TRUE]--
DisplayCurrentDate[createDate];
END; --DisplayCurrentFontDate
DisplayCurrentTestPatternDate: PSCommand.FileProc = BEGIN
[type, name, sizeInBytes, createDate]
DisplayCurrentDate[createDate];
END; --DisplayCurrentTestPatternDate
outputHandle.Blanks[10];
nsDateAndTime.length ← 0;
XFormat.Date[nsDateTimeObject, floppyFile.attributes.createDate]; --appends date to nsDateAndTime
stringArray[0] ← nsDateAndTime;
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyFileCreated, stringArray];
IF floppyFile.dataType = font THEN
PSCommand.ListFonts[proc: DisplayCurrentFontDate,
filter: [packageName: floppyFile.nsFileName]]
ELSE
PSCommand.ListFiles[proc: DisplayCurrentTestPatternDate,
filter: [type: testPattern, name: floppyFile.nsFileName]];
END; --DisplayDates
Done: PROCEDURE = TRUSTED BEGIN
OfflineFP0[];
FREE[@attributes];
END; -- Done
Install: PROCEDURE = BEGIN
ENABLE BEGIN
AccessFloppy.Error => {
IF type = volumeNotOpen THEN {
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID]};
GOTO Exit};
May be generated in SendFloppyData (Floppy.Read) among other(?) places:
Floppy.Error => {
stringArray: ARRAY [0..1) OF NSString.String;
outputHandle.CR[];
stringArray[0] ← M[
SELECT error FROM
badDisk => mFloppyErrBadDisk,
badSectors => mFloppyErrBadSectors,
hardwareError => mFloppyErrHardware,
invalidVolumeHandle => mFloppyErrInvalidVolumeHandle,
needsScavenging => mFloppyErrNeedsScavenging,
noSuchDrive => mFloppyErrNoSuchDrive,
notReady => mFloppyErrNotReady,
stringTooShort => mFloppyErrStringTooShort,
volumeNotOpen => mFloppyErrVolumeNotOpen,
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, DESCRIPTOR[stringArray]];
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyCanceled]];
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID];
GOTO Exit};
PSCommand.Error => {
WITH problem SELECT FROM
abortedByClient => NULL;
ENDCASE => {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyCanceled]]};
GOTO Exit};
END; --Enable Clause
pieceFile: BOOLEANFALSE;
BYTE: TYPE = CARDINAL [0..100];
nsPrompt: NSString.String ← NEW[NSString.StringRep[100]];
nsPrompt: NSString.String ← [bytes: promptBytes, length: 0, maxlength: 100];
promptBytes: PACKED ARRAY [0..100) OF BYTE;
ask for name confirmation
sFileName: LONG STRING ← [AccessFloppy.maxNameLength]M
floppyFile ← [];
nTestPatternsInstalled ← nFontsInstalled ← 0;
OpenVolume[labelString ! UserAbort => GOTO Exit]; -- floppyHandle, labelString, nullFloppyFileHandle will be set.
nsPrompt ← NSString.AppendString[nsPrompt, M[mInstallFromFloppy]];
nsPrompt ← NSString.AppendString[nsPrompt, labelString];
IF TextInput.GetYesNo[
tty, nsPrompt, yes ! TTY.Rubout => GOTO Exit] = no THEN GOTO Exit;
attributes ← NEW[AccessFloppy.AttributesRecord[AccessFloppy.maxDataSize]];
DO
FOR floppyFileHandle: Floppy.FileHandle ← Floppy.GetNextFile[
nullFloppyFileHandle].nextFile, Floppy.GetNextFile[floppyFileHandle].nextFile UNTIL
floppyFileHandle = nullFloppyFileHandle DO
AccessFloppy.GetAttributes[floppyFileHandle, attributes];
AccessFloppyUtil.MesaStringFromAttributes[attributes, sFileName];
IF IsScriptFile[sFileName] THEN LOOP;
pieceFile ← IsPieceFile[attributes];
floppyFile.id ← floppyFileHandle;
floppyFile.attributes ← attributes;
floppyFile.fileName ← sFileName;
floppyFile.nsFileName ← Str[sFileName];
floppyFile.dataType ←
IF floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated0 AND
floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated90 AND
floppyFile.attributes.type # PSAssignedTypes.tFont200Rotated90
THEN testPattern ELSE font;
IF floppyFile.dataType = font THEN
SELECT psState.option FROM
bansheeDl, feps9700, fx3500, raven =>
IF floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated0 THEN
GOTO WrongFontFileType;
d1 =>
d1 fonts can have either type tFont300Rotated0 or tFont300Rotated90,
though we assume they are actually the 90 degree rotated fonts.
IF (floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated0) AND
(floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated90) THEN
GOTO WrongFontFileType;
fax295, fax495 =>
IF floppyFile.attributes.type # PSAssignedTypes.tFont200Rotated90 THEN
GOTO WrongFontFileType;
ENDCASE => ERROR
ELSE BEGIN --file is a test pattern
OPEN T: TestPattern;
This is a bunch of ugly exception code to prevent the user from loading test patterns inappropriate for the printing option being supported. This only matters for the
options that use the 300 spi fonts, since they all share the same Required Fonts floppy. The 200 spi Required Fonts floppy contains only the test patterns used by the fax.
Resuming the NotFound signal below will return the name for the test pattern, even if the TP is not currently installed on the PS....
nsBansheeAlignment: NSString.String ← T.Name[T.bansheeAlignment ! T.NotFound => RESUME];
alignment pattern specific to banshee
nsAlignment: NSString.String ← T.Name[T.alignment ! T.NotFound => RESUME];
alignment pattern for electronic printers
nsDarkDusting: NSString.String ← T.Name[T.darkDusting ! T.NotFound => RESUME];
nsGreyDusting: NSString.String ← T.Name[T.greyDusting ! T.NotFound => RESUME];
SELECT psState.option FROM
d1, fx3500, raven =>
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsBansheeAlignment] THEN LOOP; --skip alignment pattern specific to banshee
bansheeDl => BEGIN
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsAlignment] THEN LOOP; --skip alignment pattern not used for banshee
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsDarkDusting] THEN LOOP; --pattern not used for banshee (bad for engine)
END;
feps9700 => BEGIN
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsBansheeAlignment] THEN LOOP; --don't use any alignment pattern
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsAlignment] THEN LOOP; --don't use any alignment pattern
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsGreyDusting] THEN LOOP; --can't be printed by 9700
END;
fax295, fax495 => NULL; --200 spi Required Fonts floppy contains only Cam.interpress.
ENDCASE => ERROR;
END;
IF pieceFile THEN {EnterScriptMode[]; EXIT};
SELECT LoadConfirmation[] FROM
no => LOOP;
cancel => EXIT;
ENDCASE;
IF floppyFile.dataType = font THEN BEGIN
PSCommand.InstallFont[
type: cdFont,
packageName: floppyFile.nsFileName,
createDate: floppyFile.attributes.createDate,
data: [proc[SendFloppyData]],
packageSizeHintInBytes: floppyFile.attributes.totalSizeInBytes !
SendDataError => EXIT;
PSCommand.Error => WITH p: problem SELECT FROM
insufficientSpace => BEGIN
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyErrInsufficientVolSpace], 2];
outputHandle.NSLine[M[mFloppyCanceled]];
END;
disallowedInCurrentMode => BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← Message.Expand[M[mConflictingMode], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
EXIT;
END;
documentInProgress => BEGIN --We CAN get here since, with the advent of remote administration, two users may be logged at the same time. One could start printing before the other finishes installing fonts.
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
outputHandle.NSLine[M[mDocInProgress]];
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← Message.Expand[M[mPleaseStopPrinting], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
END;
ENDCASE;
];
nFontsInstalled ← nFontsInstalled + 1;
END
ELSE BEGIN
PSCommand.InstallFile[
type: testPattern, name: floppyFile.nsFileName,
createDate: floppyFile.attributes.createDate,
data: [proc[SendFloppyData]],
fileSizeHintInBytes: floppyFile.attributes.totalSizeInBytes !
SendDataError => EXIT;
PSCommand.Error => WITH problem SELECT FROM
insufficientSpace => BEGIN
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyErrInsufficientVolSpace], 2];
outputHandle.NSLine[M[mFloppyCanceled]];
END;
disallowedInCurrentMode => BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← XMessage.Compose[M[mConflictingMode], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
EXIT;
END;
ENDCASE;
];
nTestPatternsInstalled ← nTestPatternsInstalled + 1;
END;
outputHandle.Blanks[10];
outputHandle.NSLine[M[mFloppyDone]];
IF NSExec.CheckForAbort[exec] THEN EXIT;
ENDLOOP;
BEGIN -- <nFontsInstalled+nTestPatternsInstalled> " files installed from <1>."
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← Str[labelString];
outputHandle.Blanks[2];
outputHandle.Decimal[nFontsInstalled + nTestPatternsInstalled];
PSExecInternal.ExpandKeyAndPrint[exec, mFilesInstalled, stringArray];
END;
Done[];
EXITS
WrongFontFileType => BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← floppyFile.nsFileName;
PSExecInternal.ExpandKeyAndPrint[exec, mBadFontFileType, stringArray];
outputHandle.NSLine[M[mFloppyCanceled]];
Done[]; continue ← no
END;
Exit => {Done[]; continue ← no};
END; --Install
IsPieceFile: PRIVATE PROC [attributes: AccessFloppy.Attributes] RETURNS [BOOLEAN] =
BEGIN RETURN [attributes.totalSize > attributes.size];
END; --IsPieceFile
IsScriptFile: PROC [name: NSString.String] RETURNS [BOOLEAN] = BEGIN
RETURN [NSString.EqualStrings[name, scriptName]];
END; --IsScriptFile
LoadConfirmation: PROCEDURE RETURNS [answer: Answer] = BEGIN
--Get confirmation from user to load file or not.
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
version: Version;
default: TextInput.YesOrNo ← no;
version ← DisplayDates[];
SELECT version FROM
new => {
stringArray[0] ← M[mFloppyNew];
default ← yes};
newer => {
stringArray[0] ← M[mFloppyNewer];
default ← yes};
same => stringArray[0] ← M[mFloppySame];
ENDCASE => stringArray[0] ← M[mFloppyOlder];
stringArray[1] ← floppyFile.nsFileName;
nsFreeThisString ← XMessage.Compose[M[mInstallFile], stringArray];
answer ←
IF TextInput.GetYesNo[
tty, nsFreeThisString, default ! TTY.Rubout => {answer ← cancel; CONTINUE}] =
yes THEN yes ELSE no;
NSString.FreeString[nsFreeThisString];
IF answer = yes THEN
BEGIN
stringArray[0] ← floppyFile.nsFileName;
outputHandle.Blanks[8];
PSExecInternal.ExpandKeyAndPrint[exec, mInstalling, stringArray];
IF state # NIL THEN state.version ← version; --*MT for multi-floppies error
END;
END; --LoadConfirmation
OfflineFP0: PROCEDURE = BEGIN
IF floppyHandle # Floppy.nullVolumeHandle THEN {
AccessFloppy.Close[!Floppy.Error => CONTINUE];
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID]};
END; -- OfflineFP0
OpenVolume: PROCEDURE [svName: LONG STRING] = BEGIN
svName.length ← 0;
floppyHandle ← AccessFloppy.Open[
!
Floppy.Error =>
SELECT error FROM
invalidVolumeHandle, notReady => {
outputHandle.CR[];
IF TextInput.GetYesNo[
tty, M[mInsertFloppy], yes ! TTY.Rubout => {GOTO Quit}] = yes
THEN RETRY
ELSE GOTO Quit};
ENDCASE => REJECT];
[] ← Floppy.GetAttributes[floppyHandle, svName];
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID];
EXITS Quit => ERROR UserAbort;
END; --OpenVolume
SendFloppyData: PROCEDURE [dataSink: NSDataStream.SinkStream] = BEGIN
bufferSize: VM.PageCount = 30; --one disk track
buffer: VM.Interval ← VM.nullInterval;
bufferBlock: Stream.Block;
pagesRemaining: VM.PageCount ← floppyFile.attributes.size;
base: Floppy.PageNumber ← AccessFloppy.leaderLength;
filePiece: BOOLEAN ← floppyFile.attributes.totalSize # floppyFile.attributes.size;
DeleteBuffer: PROCEDURE = BEGIN
IF buffer # VM.nullInterval THEN BEGIN
AccessFloppyUtil.DeleteBuffer[buffer.pointer];
buffer ← Space.nullInterval;
END;
END; --DeleteBuffer
BEGIN ENABLE
BEGIN UNWIND => {
IF dataSink # nullSinkStream THEN {
NSDataStream.Abort[dataSink ! NSDataStream.Aborted => CONTINUE];
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE]};
DeleteBuffer[]};
Floppy.Error => {
stringArray: ARRAY [0..1) OF NSString.String;
stringArray[0] ← M[
SELECT error FROM
invalidVolumeHandle => mFloppyErrInvalidVolumeHandle,
notReady => mFloppyErrNotReady,
volumeNotOpen => mFloppyErrVolumeNotOpen,
hardwareError => mFloppyErrHardware,
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, DESCRIPTOR[stringArray]];
GOTO dataSendError};
Floppy.DataError => {
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyReadError]];
GOTO dataSendError}
END; --Enable clause
IF dataSink = nullSinkStream THEN RETURN;
buffer ← AccessFloppyUtil.CreateBuffer[bufferSize !
Space.InsufficientSpace, RefText.Error => {
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyCreateFileError]];
GOTO dataSendError};
Volume.InsufficientSpace => {
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyErrInsufficientVolSpace]];
GOTO dataSendError}];
bufferBlock ← [
blockPointer: buffer.pointer, startIndex: 0,
stopIndexPlusOne: CARDINAL[bufferSize * Environment.bytesPerPage]];
Copy as many chunks of the standard buffer size as possible...
UNTIL pagesRemaining < bufferSize DO
Floppy.Read[floppyFile.id, base, bufferSize, buffer.pointer];
Stream.PutBlock[dataSink, bufferBlock !
NSDataStream.Aborted => GOTO aborted];
base ← base + bufferSize;
pagesRemaining ← pagesRemaining - bufferSize;
ENDLOOP;
...and then copy the fraction left over.
IF pagesRemaining # 0 THEN BEGIN
scratchPointer: LONG POINTER ← Space.ScratchMap[pagesRemaining];
scratchBlock: Stream.Block;
bytesRemaining: CARDINALCARDINAL[pagesRemaining * PrincOps.bytesPerPage];
scratchBlock ← [
blockPointer: scratchPointer, startIndex: 0,
stopIndexPlusOne: bytesRemaining];
Floppy.Read[floppyFile.id, base, pagesRemaining, scratchPointer !
Floppy.Error, Floppy.DataError => {
scratchPointer ← Space.Unmap[scratchPointer]; REJECT}];
Stream.PutBlock[dataSink, scratchBlock !
NSDataStream.Aborted => {
scratchPointer ← Space.Unmap[scratchPointer];
GOTO aborted}];
scratchPointer ← Space.Unmap[scratchPointer];
END;
DeleteBuffer[];
IF ~filePiece THEN
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
EXITS
aborted => { --PSCommand Install proc will return with raise error.
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
DeleteBuffer[];
systemAbort ← TRUE};
dataSendError => {
NSDataStream.Abort[dataSink ! NSDataStream.Aborted => CONTINUE];
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
DeleteBuffer[];
ERROR SendDataError};
END; --Enable clause and code
END; --SendFloppyData
IF psState.clientControl.formatterEnabled OR psState.clientControl.markerEnabled
THEN BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← M[mInstallFonts];
outputHandle.Blanks[2];
PSExecInternal.ExpandKeyAndPrint[exec, mPleaseStopPrinting, stringArray];
END
ELSE Install[];
EXITS Exit => NULL;
END; --InstallFromFloppy
=== === === === === ===
SUPPORT ROUTINES:
=== === === === === ===
Proc for getting NSString from XMessage key
M: PROCEDURE [key: PSExecMessages.Key] RETURNS [string: NSString.String] = {
RETURN[XMessage.Get[execMsgs, ORD[key]]]};
END. --PSExecEImpl
LOG when/who/what
13-Mar-85 10:26:27 - Jacks - Created. Split off from PSExecBImpl.
8-May-85 13:20:06 - Jacks - Updated to Pilot/Mesa 12.0 (change in FloppyChannel).
20-Jun-85 10:42:59 - Jacks - Added copyright notice; updated to PS Euclid interfaces; turned off public error catching by SCS in development mode.
28-Jun-85 15:10:38 - Jacks - Added d1 to case stmts; removed SetCatching calls.
18-Jul-85 14:38:21 - Jacks - Converted to XMessage.
7-Aug-85 10:12:26 - Jacks - Converted to PSCommandExtras InstallFontX, DeleteFontX and ListFontsX; added catch phrases to PSCommandExtras.InstallFont, PSCommand.InstallFile and PSCommandExtras.DeleteFont; added kludge for loading d1 fonts with the correct type.
15-Aug-85 17:05:42 - Jacks - Added catchs for PSCommand.Error[undefined] which means documentInProgress.
10-Sep-85 10:39:10 - Jacks - Moved a string to the msg file; put d1 kludge in more places.
11-Sep-85 13:27:06 - Jacks - Went back to using PSCommand.InstallFont, DeleteFont and ListFonts, instead of PSCommandExtras; removed d1 and bansheeDl font type kludges.
24-Sep-85 14:30:31 - Jacks - PSCommandExtras folded into PSCommand.
6-Nov-85 13:15:18 - Jacks - Call PSKMessages for msg handle.
13-Dec-85 16:46:58 - Jacks - ExecMessages renamed to PSExecMessages.