-- [Ivy]<Swinehart>Inscript>ClassInscript.mesa -- Last Edited by Swinehart, April 14, 1982 10:11 am DIRECTORY Intime USING [EventTime, MsTicks], Rope USING [ROPE]; 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 [fileName: Rope.ROPE, 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.