-- [Ivy]<Swinehart>Inscript>ClassInscript.mesa
-- Last Edited by Swinehart, April 14, 1982 10:11 am
-- Last Edited by Paul Rovner, June 10, 1983 9:01 am
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.
NewStdInscript: PROCEDURE [
KeyProc: KEyProc, ComProc: COmProc, initializeFile: BOOLEAN ← FALSE,
lnFileSize: CARDINAL←4, lnGroupSize: CARDINAL←2]
RETURNS [Inscript];
Inscript: TYPE = LONG POINTER TO InscriptObject;
-- Client Interface for Inscripts
-- 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.
Release: PROCEDURE [self: Inscript] RETURNS [nilInscript: Inscript];
GetPageLimits: PROCEDURE [self: Inscript]
RETURNS [earliestPageNo: InscriptPageNumber, latestPageNo: InscriptPageNumber];
-- Creates an invalid page descriptor, such that any operations applied
-- to it will fail until a SetPageDescriptor operation has been executed.
ResetPageDescriptor: PROCEDURE [self: Inscript, descriptor: InscriptPageDescriptor];
CopyPageDescriptor: PROCEDURE [self: Inscript, dest: InscriptPageDescriptor,
source: InscriptPageDescriptor];
-- 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.
SetPage: PROCEDURE [self: Inscript, descriptor: InscriptPageDescriptor,
pageNumber: InscriptPageNumber, init: BOOLEAN←FALSE] RETURNS [success: BOOLEAN];
-- Advances descriptor to describe the next page in sequence.
AdvancePage: PROCEDURE [self: Inscript, descriptor: InscriptPageDescriptor]
RETURNS [success: BOOLEAN];
-- Adds a new output page to the script, so that additional entries
-- can be made.
SetWritePage: PROCEDURE [self: Inscript] RETURNS [success: BOOLEAN];
-- 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.
ReadEntry: PROCEDURE [self: Inscript, descriptor: InscriptPageDescriptor,
destination: LONG POINTER TO UNSPECIFIED, LengthProc: LengthProcType]
RETURNS [success: BOOLEAN];
-- 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.
WriteEntry: PROCEDURE [self: Inscript, entry: LONG DESCRIPTOR FOR ARRAY OF WORD]
RETURNS [success: BOOLEAN];
waitALongTime: Intime.MsTicks=5000;
WaitForEntry: PROCEDURE [self: Inscript, waitMode: WaitMode, waitInterval: Intime.MsTicks ← waitALongTime,
descriptor: InscriptPageDescriptor, waitStartTime: LONG POINTER TO Intime.EventTime ← NIL]
RETURNS [moreEntries: BOOLEAN];
InscriptPageNumber: TYPE = INTEGER;
AccessMethod: TYPE = {read, readNext, writeNew};
OrderKey: TYPE = RECORD [a, b, c: WORD];
COmProc: TYPE = PROCEDURE [a, b: OrderKey] RETURNS [aLessB: BOOLEAN];
KEyProc: TYPE = PROCEDURE [
inscript: Inscript, descriptor: InscriptPageDescriptor] RETURNS [OrderKey];
LengthProcType: TYPE = PROCEDURE [p: LONG POINTER TO UNSPECIFIED]
RETURNS [wordsToAdvance: CARDINAL];
WaitMode: TYPE = {forever, dontWait, timed};
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 --};
-- Inscript interface implementation --
InscriptObject: TYPE;
InscriptPageDescriptor: TYPE = LONG POINTER TO InscriptPageDescBody;
InscriptPageDescBody: TYPE[4]; -- <<Need SIZE, Should be a better way>>
END.