ClassInscript.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by Swinehart, April 14, 1982 10:11 am
Last Edited by Paul Rovner, June 10, 1983 9:01 am
Doug Wyatt, April 14, 1985 8:19:03 pm PST
DIRECTORY
Intime USING [EventTime, MsTicks];
ClassInscript: DEFINITIONS
= BEGIN
An Inscript represents a sequence of recorded entries, organized in some sort of "page" units. At any time, there is a page number representing the latest page into which entries have been recorded, and another representing the earliest page which the Inscript still knows about (in some implementations old pages may be forgotten). The Inscript does not know the semantics of its entries. The client knows the semantics, and that entries are stored atomically on pages (they do not overlap boundaries), but not the size of pages or the exact means of storage. The Inscript provides operations for recording entries sequentially at the end of the sequence, for placing an "input" pointer at the beginning of a specified page, for retrieving entries sequentially from a page, and for determining the range of pages from which entries can be retrieved.
Inscript: TYPE ~ REF InscriptObject;
InscriptObject: TYPE;
AccessMethod: TYPE = {read, readNext, writeNew};
OrderKey: TYPE = RECORD [a, b, c: WORD];
COmProc: TYPE = PROC [a, b: OrderKey] RETURNS [aLessB: BOOL];
KEyProc: TYPE = PROC [inscript: Inscript, descriptor: InscriptPageDescriptor]
RETURNS
[OrderKey];
LengthProcType: TYPE = PROC [p: LONG POINTER TO UNSPECIFIED]
RETURNS
[wordsToAdvance: CARDINAL];
WaitMode: TYPE = {forever, dontWait, timed};
InscriptPageNumber: TYPE = INTEGER;
InscriptPageDescriptor: TYPE = LONG POINTER TO InscriptPageDescBody;
InscriptPageDescBody: TYPE[4]; -- <<Need SIZE, Should be a better way>>
NewStdInscript: PROC [KeyProc: KEyProc, ComProc: COmProc,
initializeFile: BOOLFALSE, lnFileSize: CARDINAL ← 4, lnGroupSize: CARDINAL ← 2
] RETURNS [Inscript];
Release: PROC [self: Inscript] RETURNS [nilInscript: Inscript];
No further operations will be supported using this Inscript; the client must know what parameters to supply when making a new one to get the old information back.
GetPageLimits: PROC [self: Inscript]
RETURNS
[earliestPageNo: InscriptPageNumber, latestPageNo: InscriptPageNumber];
ResetPageDescriptor: PROC [self: Inscript, descriptor: InscriptPageDescriptor];
Creates an invalid page descriptor, such that any operations applied to it will fail until a SetPageDescriptor operation has been executed.
CopyPageDescriptor: PROC [self: Inscript,
dest: InscriptPageDescriptor, source: InscriptPageDescriptor];
SetPage: PROC [self: Inscript, descriptor: InscriptPageDescriptor,
pageNumber: InscriptPageNumber, init: BOOLFALSE] RETURNS [success: BOOL];
The descriptor will now describe the indicated page number.
The next read will obtain the first entry on the page.
Returns FALSE if specified page does not exist at the time of call.
AdvancePage: PROC [self: Inscript, descriptor: InscriptPageDescriptor]
RETURNS
[success: BOOL];
Advances descriptor to describe the next page in sequence.
SetWritePage: PROC [self: Inscript] RETURNS [success: BOOL];
Adds a new output page to the script, so that additional entries can be made.
ReadEntry: PROC [self: Inscript, descriptor: InscriptPageDescriptor,
destination: LONG POINTER, LengthProc: LengthProcType] RETURNS [success: BOOL];
If page is not exhausted, passes pointer to next entry to LengthProc procedure. LengthProc procedure must determine the length of the entry, returning a count of the number of words used. ReadEntry then copies the entry to the destination. ReadEntry returns FALSE if the page was exhausted or the returned count would exceed the page limits. It raises NoValidPage if the Inscript no longer remembers the contents of the page. False is returned so that the client may, if desired, take special action at each page boundary. Normally, client will then call AdvancePage to move on to the next page.
WriteEntry: PROC [self: Inscript, entry: LONG DESCRIPTOR FOR ARRAY OF WORD]
RETURNS
[success: BOOL];
Returns FALSE if the contents of the descriptor will not fit in the remainder of the current output page. Otherwise copies the entry into the page. Client should call SetWritePage to move on, then perhaps take special action before continuing with normal writes.
waitALongTime: Intime.MsTicks = 5000;
WaitForEntry: PROC [self: Inscript,
waitMode: WaitMode,
waitInterval: Intime.MsTicks ← waitALongTime,
descriptor: InscriptPageDescriptor,
waitStartTime: LONG POINTER TO Intime.EventTime ← NIL
] RETURNS [moreEntries: BOOL];
InscriptError: -- Abstraction --ERROR [code: InscriptErrorCode];
InscriptErrorCode: TYPE = {
entryOutOfBounds, -- trying to position out of bounds or old stuff has disappeared
invalidInscriptSpecs, -- bad arguments to NewStd...
invalidInscriptFile, -- while opening old inscript file
descriptorUninitialized, -- in AdvancePage
invalidPageKey -- in KeyProc during intitialization
};
END.