-- File: CoreStreamDefs.mesa
-- Edited by Levin:  22-Oct-80  9:12:04
-- Edited by Schroeder:  November 18, 1980  1:49 PM


DIRECTORY
  crD: FROM "CoreDefs",
  ovD: FROM "OverviewDefs",
  Stream;

csD: DEFINITIONS =

  BEGIN


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

  StreamType: TYPE = {byte, word};

  StreamHandle: TYPE = POINTER TO CStream;

  CStream: TYPE;

  Position: TYPE = LONG CARDINAL;


  Error: ERROR [reason: ovD.ErrorCode];
  -- reason can be: endOfStream, diskFull, fileTooBig, diskError,
  -- diskCorrupted, illegalFilename, fileInUse, fileNotFound.


  -- 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.
  --
  -- The "nPages" parameter supplied at open time determines the
  -- amount of in-core buffering to be used with the stream.  If the
  -- "buffer" parameter is defaulted, the stream implementation code
  -- will supply the storage, up to the "nPages" limit.
  -- If the "buffer" parameter is explicitly supplied, the client is
  -- providing a contiguous block of "nPages" of buffer space.


  OpenFromName: PROCEDURE [
    name: STRING, user: crD.DMSUser, type: StreamType,
    mode: StreamMode, nPages: CARDINAL, buffer: POINTER ← NIL]
    RETURNS [sh: StreamHandle];
  --
  -- If the specified file does not exist, it will be created unless
  -- "mode" is "read", in which case Error[ovD.fileNotFound] will
  -- be raised.


  Open: PROCEDURE [
    fh: crD.UFileHandle, type: StreamType, mode: StreamMode,
    nPages: CARDINAL, buffer: POINTER ← NIL]
    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 csD.Error.


  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 Error[ovD.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 Error[ovD.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.
  -- ovD.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 Error[ovD.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, which ever
  -- 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
  -- maximun size of the block will be the size of
  -- the stream's buffer.  Will not raise Error[ovD.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
  -- 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 ovD.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 --