-- File: CoreStreamDefs.mesa
-- Edited by Levin: 22-Oct-80 9:12:04
-- Edited by Schroeder: November 18, 1980 1:49 PM
-- Edited by Brotz, November 19, 1981 11:39 AM


DIRECTORY
Stream USING [Block],
VMDefs USING [FileHandle];

csD: DEFINITIONS =

BEGIN

CStream: TYPE;
StreamHandle: TYPE = POINTER TO CStream;

StreamMode: TYPE = {read, overwrite, write, append};
StreamType: TYPE = {byte, word};

Position: TYPE = LONG CARDINAL;


-- Opening Streams:

-- CStreams come in two types, word and byte, determined by the "type" parameter
-- supplied at open time. A CStream consists of a sequence of items whose size is
-- determined by the stream type. Position is a zero-origin item index within the stream.

-- The "mode" in which a stream is opened determines the initial position and stream end.
-- The initial position for append mode is the end-of-file. For all other modes the initial
-- position of the stream is 0. The initial stream end for overwrite is 0. For all other
-- modes the initial stream end is the end-of-file. As the stream is used the stream end
-- advances to stay one beyond the highest written item. All modes permit reading of
-- the stream.


EndOfStream: ERROR;


OpenFromName: PROCEDURE [name: STRING, type: StreamType, mode: StreamMode]
RETURNS [sh: StreamHandle];
-- If the specified file does not exist, it will be created unless "mode" is "read", in which
-- case VMDefs.CantOpen[notFound] will be raised.


Open: PROCEDURE [fh: VMDefs.FileHandle, type: StreamType, mode: StreamMode]
RETURNS [sh: StreamHandle];
-- It is permissable for "fh" to be NIL. In this case, the data will be buffered in core until
-- a backing file is needed. At this point, a temporary backing file is gotten from the
-- TempFileManager. The initial stream end when no backing file is provided is 0.


Checkpoint: PROCEDURE [sh: StreamHandle];
-- Remembers the current position and stream end for a subsequent Reset.
-- Causes SysBug if the current position is beyond the stream end, i.e. you’ve done a
-- SetPosition to beyond the stream end without a subsequent write.
-- If there is a backing file then any in-core dirty pages are flushed to disk and the size
-- of the backing file is set to match the stream end.


Destroy: PROCEDURE [sh: StreamHandle];
-- Destroys the stream without performing the actions of Checkpoint.
-- "sh" becomes invalid and may not be reused. Destroy cannot raise ERRORs.


Close: PROCEDURE [sh: StreamHandle] = INLINE {Checkpoint[sh]; Destroy[sh]};


Reset: PROCEDURE [sh: StreamHandle];
-- Restores the position and stream end to what they were immediately after the stream was
-- opened or last checkpointed. Items within the restored stream end that were written
-- after the last checkpoint retain their new value.


GetType: PROCEDURE [sh: StreamHandle] RETURNS [type: StreamType];


Read: PROCEDURE [sh: StreamHandle] RETURNS [item: UNSPECIFIED];
-- Raises EndOfStream if the current position is at stream end.


Write: PROCEDURE [sh: StreamHandle, item: UNSPECIFIED];


ReadBlock: PROCEDURE [sh: StreamHandle, to: POINTER, start, nItems: CARDINAL]
RETURNS [n: CARDINAL];
-- Copies up to "nItems" to the user-provided storage block beginning at "@to[start]".
-- "n" is the number of items actually copied. which may be < "nItems" if the read
-- crosses the stream end. Will not raise EndOfStream.


WriteBlock: PROCEDURE [sh: StreamHandle, from: POINTER, start, nItems: CARDINAL];
-- Copies "nItems" from the user-provided storage block beginning at "@from[start]" to "sh".


StreamCopy: PROCEDURE [from, to: StreamHandle, fromItems: LONG CARDINAL];
-- Copies "fromItems" from the "from" stream to the "to" stream. exD.SysBug if
-- (from.type = byte) AND (to.type = word) AND (nItems MOD 2 = 1).
-- StreamCopy between two streams on the same file works as long as the "to" (byte)
-- position is <= the "from" (byte) position, i.e. as long as you are copying down.
-- Copying up on the same file isn’t recommended. Will not raise EndOfStream.


ReadStream: PROCEDURE
[sh: StreamHandle, nItems: LONG CARDINAL, AcceptBlock: PROCEDURE[Stream.Block]];
-- Calls "AcceptBlock" for each block of "sh" from the current position, to that plus "nItem"
-- or to the stream’s end, whichever comes first. "startIndex" in the Stream.Block will be
-- even unless "sh" is a byte stream and the current position is odd. "stopIndexPlusOne"
-- will be even except sometimes for the last block. The maximum size of the block will
-- be one page. Will not raise EndOfStream.


GetLength: PROCEDURE [sh: StreamHandle] RETURNS [position: Position];
-- Returns the current stream end position.


GetPosition: PROCEDURE [sh: StreamHandle] RETURNS [position: Position];
-- Returns the item postion for the next item to be read or to be written on "sh".


SetPosition: PROCEDURE [sh: StreamHandle, position: Position];
-- Positions the stream so that the next item read or written will be at ’position’. Unless
-- the stream mode is read, positioning beyond the stream end is legal, but the stream
-- end will not be advanced until a write occurs. Positioning beyond the stream end on
-- a read mode stream causes an exD.SysBug.


MapPageWordToPosition: PROCEDURE [page: CARDINAL, word: CARDINAL]
RETURNS [position: Position];
-- The input <page, word> need not be normalized. The result is a word position.


MapPositionToPageWord: PROCEDURE [position: Position]
RETURNS [page: CARDINAL, word: [0 .. 377B]];
-- Maps the input word position to the corresponding page, word.


MapPageByteToPosition: PROCEDURE [page: CARDINAL, byte: CARDINAL]
RETURNS [position: Position];
-- The input <page, byte> need not be normalized. The result is a byte position.


MapPositionToPageByte: PROCEDURE [position: Position]
RETURNS [page: CARDINAL, byte: [0 .. 777B]];
-- Maps the input byte position to the corresponding page, byte.


END. -- of CoreStreamDefs --