-- StreamIO.Mesa  Edited by Sandman on August 1, 1980  10:20 AM
-- Updated for Pilot Martin Newell 29-Oct-81 18:00:54

DIRECTORY
  IODefs USING [SP, CR, NumberFormat],
  StreamDefs USING [StreamHandle, GetDefaultDisplayStream],
  String USING [SubString, StringToNumber, AppendChar, AppendNumber];

StreamIO: PROGRAM
  IMPORTS StreamDefs, String
  EXPORTS IODefs =

  BEGIN OPEN IODefs, StreamDefs, String;

  in, out: StreamHandle;
  
  GetInputStream: PUBLIC PROCEDURE RETURNS [StreamHandle] = BEGIN RETURN[in] END;

  GetOutputStream: PUBLIC PROCEDURE RETURNS [StreamHandle] = BEGIN RETURN[out] END;

  SetInputStream: PUBLIC PROCEDURE [s: StreamHandle] =
    BEGIN
    in ← s;
    END;

  SetOutputStream: PUBLIC PROCEDURE [s: StreamHandle] =
    BEGIN
    out ← s;
    END;

  SetEcho: PUBLIC PROCEDURE [new: BOOLEAN] RETURNS [old: BOOLEAN] =
    BEGIN
--    IF in.tty#NILTTY THEN RETURN[TTY.SetEcho[in.tty, new]]
--    ELSE RETURN[FALSE];
    RETURN[TRUE];
    END;

  -- Character operations


  ReadChar: PUBLIC PROCEDURE RETURNS [CHARACTER] = BEGIN RETURN[in.get[in]]; END;

  WriteChar: PUBLIC PROCEDURE [c: CHARACTER] =
    BEGIN out.put[out,c]; END;

  -- Reading Strings


  GetString: PROCEDURE [s: STRING, t: PROCEDURE [CHARACTER] RETURNS [BOOLEAN]] RETURNS[CHARACTER] =
    BEGIN
--    IF in.tty#NILTTY THEN RETURN[TTY.GetEditedString[in.tty,s,t,TRUE]]
--    ELSE
--    {	s.length ← 0;
--    	DO
--    		c: CHARACTER ← ReadChar[];
--		IF t[c] THEN RETURN[c];
--		AppendChar[s,c];
--    	ENDLOOP;
--    };
    RETURN[''];
    END;

  ReadString: PUBLIC PROCEDURE [s: STRING, t: PROCEDURE [CHARACTER] RETURNS [BOOLEAN]] =
    BEGIN
    [] ← GetString[s,t];
    END;

  ReadID: PUBLIC PROCEDURE [s: STRING] =
    BEGIN
    ReadString[s, IsAtom];
    END;

  ReadLine: PUBLIC PROCEDURE [s: STRING] =
    BEGIN
    ReadString[s, IsCR];
    END;

  IsCR: PRIVATE PROCEDURE [c: CHARACTER] RETURNS [BOOLEAN] =
    BEGIN RETURN[c = CR] END;

  IsAtom: PRIVATE PROCEDURE [c: CHARACTER] RETURNS [BOOLEAN] =
    BEGIN RETURN[c=SP OR c=CR] END;

  Rubout: PUBLIC SIGNAL = CODE;
  LineOverflow: PUBLIC SIGNAL [s: STRING] RETURNS [ns: STRING] = CODE;

  ReadEditedString: PUBLIC PROCEDURE [
    s: STRING, t: PROCEDURE [CHARACTER] RETURNS [BOOLEAN], newstring: BOOLEAN]
    RETURNS [CHARACTER] =
    BEGIN
--    IF in.tty#NILTTY THEN RETURN[TTY.GetEditedString[in.tty,s,t,newstring]]
--    ELSE RETURN[GetString[s,t]];
    RETURN[''];
    END;

  -- Writing Strings


  WriteString: PUBLIC PROCEDURE [s: STRING] =
    BEGIN
    i: CARDINAL;
    FOR i IN [0..s.length) DO out.put[out, s[i]]; ENDLOOP;
    END;

  WriteSubString: PUBLIC PROCEDURE [s: String.SubString] =
    BEGIN
    i: CARDINAL;
    FOR i IN [s.offset..s.offset + s.length) DO out.put[out, s.base[i]]; ENDLOOP;
    END;

  WriteLine: PUBLIC PROCEDURE [s: STRING] = BEGIN WriteString[s]; WriteChar[CR]; END;

  NewLine: PUBLIC PROCEDURE RETURNS [BOOLEAN] =
    BEGIN
    WriteChar[CR];
    RETURN[TRUE];
    END;

  --  Numerical i/o


  ReadNumber: PUBLIC PROCEDURE [default: UNSPECIFIED, radix: CARDINAL]
    RETURNS [UNSPECIFIED] =
    BEGIN
    s: STRING ← [10];
    IF radix = 10 AND LOOPHOLE[default, INTEGER] < 0 THEN
      BEGIN default ← -default; s[0] ← '-; s.length ← 1 END;
    AppendNumber[s, default, radix];
    IF radix = 8 THEN AppendChar[s, 'B];
    [] ← ReadEditedString[s, IsAtom, TRUE];
    RETURN[StringToNumber[s, radix]];
    END;

  ReadDecimal: PUBLIC PROCEDURE RETURNS [INTEGER] =
    BEGIN
    s: STRING ← [10];
    [] ← ReadEditedString[s, IsAtom, TRUE];
    RETURN[StringToNumber[s, 10]]
    END;

  ReadOctal: PUBLIC PROCEDURE RETURNS [UNSPECIFIED] =
    BEGIN
    s: STRING ← [10];
    [] ← ReadEditedString[s, IsAtom, TRUE];
    RETURN[StringToNumber[s, 8]]
    END;

  OutNumber: PUBLIC PROCEDURE [
    stream: StreamHandle, val: INTEGER, format: NumberFormat] =
    BEGIN
    i: CARDINAL;
    neg: BOOLEAN ← FALSE;
    fill: CHARACTER ← (IF format.zerofill THEN '0 ELSE ' );
    s: STRING ← [17];
    IF val < 0 AND ~format.unsigned THEN BEGIN val ← -val; neg ← TRUE END;
    AppendNumber[s, val, format.base];
    i ← s.length;
    IF neg THEN
      BEGIN
      i ← i + 1;
      IF format.zerofill THEN BEGIN stream.put[stream, '-]; neg ← FALSE END;
      END;
    THROUGH (i..format.columns] DO stream.put[stream, fill] ENDLOOP;
    IF neg THEN stream.put[stream, '-];
    FOR i IN [0..s.length) DO stream.put[stream, s[i]] ENDLOOP;
    RETURN
    END;

  WriteNumber: PUBLIC PROCEDURE [v: UNSPECIFIED, f: NumberFormat] =
    BEGIN OutNumber[out, v, f]; RETURN END;

  WriteDecimal: PUBLIC PROCEDURE [n: INTEGER] =
    BEGIN WriteNumber[n, NumberFormat[10, FALSE, FALSE, 0]]; RETURN END;

  WriteOctal: PUBLIC PROCEDURE [n: UNSPECIFIED] =
    BEGIN
    WriteNumber[n, NumberFormat[8, FALSE, TRUE, 0]];
    IF n ~IN [0..7] THEN WriteChar['B];
    RETURN
    END;
    

    
--START code--

    out ← GetDefaultDisplayStream[];
  
  END.