-- Streams.mesa  Edited by Sandman on September 30, 1980  5:24 PM

DIRECTORY
  SegmentDefs USING [GetFileTimes, SetFileTimes],
  Segments USING [Access, AllAccess, DefaultAccess, FHandle, Read, ReadWrite, Write],
  StreamDefs USING [
    CleanupDiskStream, CloseDiskStream, CreateByteStream, DiskHandle, FileLength,
    GetPosition, IndexToPosition, NewByteStream, OpenDiskStream, SetPosition, ReadBlock,
    StreamError, WriteBlock],
  Time USING [Packed];


Streams: DEFINITIONS IMPORTS SegmentDefs, StreamDefs =
  BEGIN

  Address: TYPE = POINTER;

  -- Assert: The word POINTER does not appear below here.

  Handle: TYPE = PRIVATE StreamDefs.DiskHandle;

  Access: TYPE = PRIVATE Segments.Access;
  AllAccess: Access = Segments.AllAccess;
  DefaultAccess: Access = Segments.DefaultAccess;
  Read: Access = Segments.Read;
  ReadWrite: Access = Segments.ReadWrite;
  Write: Access = Segments.Write;

  End: PROCEDURE RETURNS [SIGNAL] = INLINE {
    RETURN[LOOPHOLE[StreamDefs.StreamError]]};

  Cleanup: PROCEDURE [h: Handle] = INLINE {StreamDefs.CleanupDiskStream[h]};

  CreateStream: PROCEDURE [file: Segments.FHandle, access: Access ← Read]
    RETURNS [Handle] = INLINE {RETURN[StreamDefs.CreateByteStream[file, access]]};

  Destroy: PROCEDURE [h: Handle] = INLINE {h.destroy[h]};

  Ended: PROCEDURE [h: Handle] RETURNS [BOOLEAN] = INLINE {RETURN[h.endof[h]]};

  FileFromStream: PROCEDURE [h: Handle] RETURNS [Segments.FHandle] =
    INLINE {RETURN[h.file]};

  GetIndex: PROCEDURE [h: Handle] RETURNS [LONG CARDINAL] = INLINE {
    RETURN[StreamDefs.GetPosition[h]]};

  GetLength: PROCEDURE [h: Handle] RETURNS [LONG CARDINAL] = INLINE {
    RETURN[StreamDefs.IndexToPosition[StreamDefs.FileLength[h]]]};

  GetTimes: PROCEDURE [h: Handle] RETURNS [create, write, read: Time.Packed] = INLINE {
    [create: create, write: write, read: read] ← SegmentDefs.GetFileTimes[h.file]};

  NewStream: PROCEDURE [name: STRING, access: Access ← Read] RETURNS [Handle] =
    INLINE {RETURN[StreamDefs.NewByteStream[name, access]]};

  Restart: PROCEDURE [h: Handle] = INLINE {StreamDefs.OpenDiskStream[h]};

  SetIndex: PROCEDURE [h: Handle, i: LONG CARDINAL] = INLINE {
    StreamDefs.SetPosition[h, i]};

  SetTimes: PROCEDURE [h: Handle, create, write, read: Time.Packed] = INLINE {
    SegmentDefs.SetFileTimes[file: h.file, create: create, write: write, read: read]};

  Suspend: PROCEDURE [h: Handle] = INLINE {StreamDefs.CloseDiskStream[h]};

  GetBlock: PROCEDURE [h: Handle, a: Address, words: CARDINAL]
    RETURNS [CARDINAL] = INLINE {RETURN[StreamDefs.ReadBlock[h, a, words]]};

  GetByte: PROCEDURE [h: Handle] RETURNS [UNSPECIFIED [0..256)] = INLINE {
    RETURN[h.get[h]]};

  GetChar: PROCEDURE [h: Handle] RETURNS [CHARACTER] = INLINE {
    RETURN[h.get[h]]};

  GetWord: PROCEDURE [h: Handle] RETURNS [UNSPECIFIED] = INLINE {
    t: CARDINAL = CARDINAL[h.get[h]]*256; RETURN[h.get[h] + t]};

  PutBlock: PROCEDURE [h: Handle, a: Address, words: CARDINAL]
    RETURNS [CARDINAL] = INLINE {RETURN[StreamDefs.WriteBlock[h, a, words]]};

  PutByte: PROCEDURE [h: Handle, u: UNSPECIFIED [0..256)] = INLINE {h.put[h, u]};

  PutChar: PROCEDURE [h: Handle, c: CHARACTER] = INLINE {h.put[h, c]};

  PutWord: PROCEDURE [h: Handle, u: UNSPECIFIED] = INLINE {
    h.put[h, CARDINAL[u]/256]; h.put[h, CARDINAL[u] MOD 256]};

  END.