-- Stream.mesa, edit:
  -- MAS: Apr 18, 1980 4:20 PM
  -- HGM: October 16, 1979  10:57 PM

-- Copyright  Xerox Corporation 1979, 1980

Stream: DEFINITIONS =
BEGIN

Handle: TYPE = POINTER TO Object;
Byte: TYPE = [0..255];
Word: TYPE = [0..65535];
SubSequenceType: TYPE = [0..256);

Block: TYPE = RECORD [ -- descriptor for arbitrary sequence of bytes
  blockPointer: LONG POINTER, 
  startIndex, stopIndexPlusOne: CARDINAL];

InputOptions: TYPE = RECORD [
terminateOnEndPhysicalRecord, signalLongBlock, signalShortBlock, signalSSTChange, signalEndOfStream: BOOLEAN];

defaultInputOptions: InputOptions = [FALSE, FALSE, FALSE, FALSE, FALSE];
CompletionCode: TYPE = {normal, endRecord, sstChange, endOfStream};

GetBlock: PROCEDURE [sH: Handle, block: Block]
  RETURNS [bytesTransferred: CARDINAL, why: CompletionCode, sst: SubSequenceType] = INLINE
  BEGIN
  [bytesTransferred, why, sst] ← sH.get[sH, block, sH.options];
  END;

SetInputOptions: PROCEDURE [sH: Handle, options: InputOptions] = INLINE
  BEGIN
  sH.options ← options;
  END;

PutBlock: PROCEDURE [sH: Handle, block: Block, endPhysicalRecord: BOOLEAN] = INLINE
  BEGIN
  sH.put[sH, block, endPhysicalRecord];
  END;

GetByte: PROCEDURE [sH: Handle] RETURNS [byte: Byte];
GetChar: PROCEDURE [sH: Handle] RETURNS [char: CHARACTER];
GetWord: PROCEDURE [sH: Handle] RETURNS [word: Word];

PutByte: PROCEDURE [sH: Handle, byte: Byte];
PutChar: PROCEDURE [sH: Handle, char: CHARACTER];
PutWord: PROCEDURE [sH: Handle, word: Word];

SendNow: PROCEDURE [sH: Handle] = INLINE
  BEGIN
  bl: Block = [NIL, 0, 0];
  sH.put[sH, bl, TRUE];
  END;

SetSST: PROCEDURE [sH: Handle, sst: SubSequenceType] = INLINE
  BEGIN
  sH.setSST[sH, sst];
  END;

SendAttention: PROCEDURE [sH: Handle, byte: Byte] = INLINE
  BEGIN
  sH.sendAttention[sH, byte];
  END;

WaitForAttention: PROCEDURE [sH: Handle] RETURNS [Byte] = INLINE
  BEGIN
  RETURN[sH.waitAttention[sH]];
  END;

Delete: PROCEDURE [sH: Handle] = INLINE
  BEGIN
  sH.delete[sH];
  END;

	--The following are the signals which can be generated by a Stream
SSTChange: SIGNAL [sst: SubSequenceType, nextIndex: CARDINAL];
EndOfStream: SIGNAL [nextIndex: CARDINAL];
TimeOut: SIGNAL [nextIndex: CARDINAL];
LongBlock: SIGNAL [nextIndex: CARDINAL];
ShortBlock: ERROR;

	--The following are the types used by implementors of filters and transducers
Object: TYPE = RECORD [
options: InputOptions,
get: GetProcedure,
put: PutProcedure,
setSST: SetSSTProcedure,
sendAttention: SendAttentionProcedure,
waitAttention: WaitAttentionProcedure,
delete: DeleteProcedure];

GetProcedure: TYPE = PROCEDURE [sH: Handle, block: Block, options: InputOptions]
  RETURNS [bytesTransferred: CARDINAL, why: CompletionCode, sst: SubSequenceType];
PutProcedure: TYPE = PROCEDURE [sH: Handle, block: Block, endPhysicalRecord: BOOLEAN];
SetSSTProcedure: TYPE = PROCEDURE [sH: Handle, sst: SubSequenceType];
SendAttentionProcedure: TYPE = PROCEDURE [sH: Handle, byte: Byte];
WaitAttentionProcedure: TYPE = PROCEDURE [sH: Handle] RETURNS [Byte];
DeleteProcedure: TYPE = PROCEDURE [sH: Handle];

END.