Skip to content

Language Specification (G) : IO Library Interfaces

Benjamin Kowarsch edited this page Jan 12, 2024 · 8 revisions

IO Library Interfaces

Group IO Aggregators

Group IO aggregators are modules that import and re-export the IO library modules for a given group of types. They represent the top user-level of the type specific IO library. The standard library defines two group IO aggregator modules:

PervasiveIO

IO aggregator PervasiveIO imports and re-exports the IO library modules for the pervasive types.

INTERFACE MODULE PervasiveIO;
IMPORT BooleanIO+, CharIO+, UnicharIO+,
  OctetIO+, CardinalIO+, LongCardIO+, IntegerIO+, LongIntIO+, RealIO+, LongRealIO+;
END PervasiveIO.

MachineTypeIO

IO aggregator MachineTypeIO imports and re-exports the IO library modules for the machine types.

INTERFACE MODULE MachineTypeIO;
IMPORT ByteIO+, WordIO+, LongWordIO+, AddressIO+;
END MachineTypeIO.

Type Specific IO Aggregators

The standard library defines 14 type specific IO aggregator modules, one for each pervasive type and one for each machine type. Each type specific IO aggregator imports and re-exports the IO modules for values and arrays of a given type.

The module identifier of a type specific IO aggregator for a given type T is composed from the titlecase transformed identifier of type T, followed by suffix IO. Type identifiers with prefix LONG are considered two words, others are considered one word. Thus, the titlecase transformation of UNICHAR is Unichar, but that of LONGCARD is LongCard.

The IO aggregator for a given type T may be generated from the template* below by replacing

  • all occurrences of <#TypeIdent#> with the identifier of type T, and
  • all occurrences of <#TitleCasedTypeIdent#> with the titlecase transformation of the identifier of type T.

Common template for pervasive types and machine types

INTERFACE MODULE <#TitleCasedTypeIdent#>IO;
IMPORT Sole<#TypeIdent#>IO+, Array<#TypeIdent#>IO+;
END <#TitleCasedTypeIdent#>IO.

[*] Template expansion may easily be automated using the Unix awk or sed utilities.

Type Specific Value IO Modules

The standard library defines 14 type specific value IO modules, one for each pervasive type and one for each machine type. Each type specific value IO module provides IO bindings for reading and writing sole values of a given type.

The module identifier of a type specific value IO module for a given type T is composed from prefix Sole, followed by the titlecase transformed identifier of type T, followed by suffix IO.

The interface of a value IO module for a given type T may be generated from one of the two templates below by replacing

  • all occurrences of <#TypeIdent#> with the identifier of type T, and
  • all occurrences of <#TitleCasedTypeIdent#> with the titlecase transformation of the identifier of type T.

Template for pervasive types

INTERFACE MODULE Sole<#TitleCasedTypeIdent#>IO;
IMPORT IOChannel;
PROCEDURE [READ] Read ( chan : IOChannel; VAR value : <#TypeIdent#> );
PROCEDURE [WRITE] Write ( chan : IOChannel; value : <#TypeIdent#> );
PROCEDURE [WRITE#] WriteF ( chan : IOChannel; CONST fmtStr : ARRAY OF CHAR; value : <#TypeIdent#> );
END Sole<#TitleCasedTypeIdent#>IO.

Template for machine types

INTERFACE MODULE Sole<#TitleCasedTypeIdent#>IO;
IMPORT UNSAFE, IOChannel;
PROCEDURE [READ] Read ( chan : IOChannel; VAR value : UNSAFE.<#TypeIdent#> );
PROCEDURE [WRITE] Write ( chan : IOChannel; value : UNSAFE.<#TypeIdent#> );
PROCEDURE [WRITE#] WriteF
  ( chan : IOChannel; CONST fmtStr : ARRAY OF CHAR; value : UNSAFE.<#TypeIdent#> );
END Sole<#TitleCasedTypeIdent#>IO.

Type Specific Array IO Modules

The standard library defines 14 type specific array IO modules, one for each pervasive type and one for each machine type. Each type specific array IO module provides IO bindings for reading and writing arrays of a given type.

The module identifier of a type specific array IO module for a given type T is composed from prefix ArrayOf, followed by the titlecase transformed identifier of type T, followed by suffix IO.

The interface of an array IO module for a given type T may be generated from one of the two templates below by replacing

  • all occurrences of <#TypeIdent#> with the identifier of type T, and
  • all occurrences of <#TitleCasedTypeIdent#> with the titlecase transformation of the identifier of type T.

Template for pervasive types

INTERFACE MODULE ArrayOf<#TitleCasedTypeIdent#>IO;
IMPORT IOChannel;
PROCEDURE [READ] Read ( chan : IOChannel; VAR array : ARRAY OF <#TypeIdent#> );
PROCEDURE [WRITE] Write ( chan : IOChannel; CONST array : ARRAY OF <#TypeIdent#> );
PROCEDURE [WRITE#] WriteF
  ( chan : IOChannel; CONST fmtStr : ARRAY OF CHAR; CONST array : ARRAY OF <#TypeIdent#> );
END ArrayOf<#ModuleIdent#>IO.

Template for machine types

INTERFACE MODULE ArrayOf<#TitleCasedTypeIdent#>IO;
IMPORT UNSAFE, IOChannel;
PROCEDURE [READ] Read ( chan : IOChannel; VAR array : ARRAY OF UNSAFE.<#TypeIdent#> );
PROCEDURE [WRITE] Write ( chan : IOChannel; CONST array : ARRAY OF UNSAFE.<#TypeIdent#> );
PROCEDURE [WRITE#] WriteF
  ( chan : IOChannel; CONST fmtStr : ARRAY OF CHAR; CONST array : ARRAY OF UNSAFE.<#TypeIdent#> );
END ArrayOf<#TitleCasedTypeIdent#>IO.

Channel Based IO

StdIO

INTERFACE MODULE StdIO;
IMPORT IOChannel, IOStatus;
PROCEDURE [STDIN] in : IOChannel <*INLINE*>;
PROCEDURE [STDOUT] out : IOChannel <*INLINE*>;
PROCEDURE err : IOChannel <*INLINE*>; (* for use by RTS *)
PROCEDURE SetStdIn ( chan : IOChannel; VAR status : IOStatus );
PROCEDURE SetStdOut ( chan : IOChannel; VAR status : IOStatus );
PROCEDURE SetStdErr ( chan : IOChannel; VAR status : IOStatus );
END StdIO.

IOChannel

INTERFACE MODULE IOChannel;
(* Generic IO Channel Type *)
IMPORT IOStatus, IOAccessMode, IOSize;
TYPE IOChannel = POINTER TO Descriptor;
TYPE Descriptor = RECORD ( NIL )
  (* method slots for status handling *)
  statusOf : PROCEDURE ( IOChannel ) : IOStatus;
  StatusMsg : PROCEDURE ( IOChannel; IOStatus );
  SetStatus : PROCEDURE ( IOChannel; IOStatus, BOOLEAN );
  (* method slots for access mode query *)
  isReadable : PROCEDURE ( IOChannel ) : BOOLEAN;
  isWritable : PROCEDURE ( IOChannel ) : BOOLEAN;
  (* method slots for generic input *)
  dataReady : PROCEDURE ( IOChannel; IOSize ) : BOOLEAN;
  ReadOctet : PROCEDURE ( IOChannel; VAR OCTET );
  ReadBlock : PROCEDURE ( IOChannel; VAR ARRAY OF OCTET );
  insertReady : PROCEDURE ( IOChannel ) : BOOLEAN;
  Insert : PROCEDURE ( IOChannel, OCTET );
  (* method slots for generic output *)
  WriteOctet : PROCEDURE ( IOChannel; OCTET );
  WriteBlock : PROCEDURE ( IOChannel; ARRAY OF OCTET; VAR IOSize );
  isFlushable : PROCEDURE ( IOChannel ) : BOOLEAN;
  Flush : PROCEDURE ( IOChannel )
END; (*Descriptor*)
END IOChannel.

IOSize

INTERFACE MODULE IOSize;
TYPE IOSize = ALIAS OF LONGCARD;
END IOSize.

On systems where the maximum file size exceeds LONGCARD, type IOSize may be redefined and the IO library rebuilt.

IOAccessMode

INTERFACE MODULE IOAccessMode;
(* IO Access Mode Common to all Channel Drivers *)
CONST
  RO = { Flags.Read };
  WO = { Flags.Write };
  RW = { Flags.Read, Flags.Write };
TYPE IOAccessMode = SET OF Flags;
TYPE Flags =
  ( Read,    (* reading is permitted if set *)
    Write ); (* writing is permitted if set *)
END IOAccessMode.

FileChannel

INTERFACE MODULE FileChannel;
(* FileIO Specific IO Channel Type *)
IMPORT IOChannel, IOStatus, FileMode, IOSize, FileIO;
TYPE FileChannel = POINTER TO Descriptor;
PROCEDURE [NEW] New ( VAR chan : FileChannel ); (* allocates channel, initialises method slots *)
PROCEDURE [RETAIN] Retain ( VAR chan : FileChannel ); (* prevents inadvertent closing of channel *)
PROCEDURE [RELEASE] Release ( VAR chan : FileChannel ); (* closes channel when refcount is zero *)
PROCEDURE isFileChannel ( chan : IOChannel ) : BOOLEAN;
TYPE FilePos = ALIAS OF IOSize;
TYPE Descriptor = RECORD ( IOChannel )
  (* inherits generic channel method slots *)
  (* FileChannel specific method slots *)
  Open : PROCEDURE ( FileChannel, (*filename:*) CONST ARRAY OF CHAR, FileMode, VAR IOStatus );
  ReOpen : PROCEDURE ( FileChannel, FileMode );
  (* method slots for access mode and filename query *)
  modeOf : PROCEDURE ( FileChannel ) : FileMode;
  nameLen : PROCEDURE ( FileChannel ) : LONGCARD;
  GetName : PROCEDURE ( FileChannel; (*filename:*) VAR ARRAY OF CHAR );
  (* positioning *)
  isValidPos : PROCEDURE ( FileChannel; FilePos ) : FilePos;
  lastValidSetPos : PROCEDURE ( FileChannel ) : FilePos;
  SetPos : PROCEDURE ( FileChannel; (*position:*) FilePos );
  Advance : PROCEDURE ( FileChannel; (*offset:*) FilePos );
  Rewind : PROCEDURE ( FileChannel );
  handle : FileIO.File (* file handle is a FileIO handle *)
END; (*Descriptor*)
END FileChannel.

FileIO

INTERFACE MODULE FileIO; (* Abstract Low-Level File IO *)
IMPORT IOSize, IOStatus, FileMode;
TYPE File = OPAQUE POINTER; FilePos = ALIAS OF IOSize;
PROCEDURE defaultInFile : File;
PROCEDURE defaultOutFile : File;
PROCEDURE defaultErrFile : File;
PROCEDURE isValidAccessor ( file : File ) : BOOLEAN;
PROCEDURE isSpecialFile ( file : File ) : BOOLEAN;
PROCEDURE Open
  ( NEW file : File; CONST filename : ARRAY OF CHAR; mode : FileMode; VAR status : IOStatus );
PROCEDURE ReOpen ( file : File; mode : FileMode );
PROCEDURE statusOf ( file : File ) : IOStatus;
PROCEDURE StatusMsg ( file : File; status : IOStatus );
PROCEDURE SetStatus ( file : File; status : IOStatus; VAR valid : BOOLEAN );
PROCEDURE modeOf ( file : File ) : FileMode;
PROCEDURE nameLen ( file : File ) : CARDINAL;
PROCEDURE GetName ( file : File; VAR filename : ARRAY OF CHAR );
PROCEDURE eof ( file : File ) : BOOLEAN;
PROCEDURE currentPos ( file : File ) : FilePos;
PROCEDURE isValidPos ( file : File; pos : FilePos ) : BOOLEAN;
PROCEDURE lastValidSetPos ( file : File ) : FilePos;
PROCEDURE SetPos ( file : File; pos : FilePos );
PROCEDURE Advance ( file : File; offset : FilePos );
PROCEDURE Rewind ( file : File );
PROCEDURE dataReady ( file : File; octets : IOSize ) : BOOLEAN;
PROCEDURE ReadOctet ( file : File; VAR data : OCTET );
PROCEDURE ReadBlock ( file : File; VAR data : ARRAY OF OCTET );
PROCEDURE insertReady ( file : File ) : BOOLEAN;
PROCEDURE Insert ( file : File; data : OCTET );
PROCEDURE WriteOctet ( file : File; data : OCTET );
PROCEDURE WriteBlock ( file : File; data : ARRAY OF OCTET; VAR octetsWritten : IOSize );
PROCEDURE isFlushable ( file : File ) : BOOLEAN;
PROCEDURE Flush ( file : File );
PROCEDURE Close ( VAR file : File; VAR status : IOStatus );
END FileIO.

IOStatus

INTERFACE MODULE IOStatus;
IMPORT Status, StatusCode;
TYPE IOStatus = RECORD ( Status )
  (* inherits failed : BOOLEAN *)
  code : IOStatusCode
END; (*IOStatus*)
END IOStatus.

IOStatusCode

INTERFACE MODULE IOStatusCode;
IMPORT StatusCode;
TYPE IOStatusCode =
  ( +StatusCode,            (* inherits Success and Failure       *)
     FileNotFound,          (* no file found with this filename   *)
     NameTooLong,           (* the passed filename is too long    *)
     IllegalCharsInName,    (* illegal chars in passed filename   *)
     InvalidMode,           (* the passed mode is invalid         *)
     AlreadyOpen,           (* the passed file is already open    *)
     MayNotOpenDirectory,   (* attempt to open a directory        *)
     AccessDenied,          (* the filesystem denied file access  *)
     AccessBeyondEOF,       (* attempt to read past end of file   *)
     NotOpenForReading,     (* file is not in Read mode           *)
     NotOpenForWriting,     (* file is not in Write/Append mode   *)
     OutOfRange,            (* input data is out of target range  *)
     WrongFormat,           (* input data is in unexpected format *)
     UnexpectedEndOfLine,   (* unexpected end−of−line in input    *)
     UnexpectedEndOfInput,  (* unexpected end of input data       *)
     ConnectionClosed,      (* remote end closed the connection   *)
     InvalidFilePos,        (* attempt to set a invalid position  *)
     InsertBufferFull,      (* capacity of insert buffer exceeded *)
     FileSizeLimitExceeded, (* attempt to write past size limit   *)
     OpenFileLimitExceeded, (* attempt to open too many files     *)
     OperationNotSupported, (* unsupported operation attempted    *)
     DeviceFull,            (* the device capacity is exceeded    *)
     DeviceError );         (* the device reported a failure      *)
END IOStatusCode.

FileMode

INTERFACE MODULE FileMode;
IMPORT IOAccessMode;
CONST
  RO = { Flags.Read };
  WO = { Flags.Write };
  RW = { Flags.Read, Flags.Write };
TYPE FileMode = SET OF Flags;
(* The file access mode consists of four flags: read, write, append and sync.
   These flags may be combined arbitrarily, subject to the following rules:
   (1) a file mode may not be the empty set
   (2) append may not be set if read is set
   (3) append may only be set if write is set
   (4) sync may only be set if write is set *)
TYPE Flags =
  ( +IOAccessMode.Flags, (* inherits Read and Write *)
    Append,              (* writing always appends if set *)
    Sync );              (* writing always flushes if set *)
PROCEDURE isValid ( mode : FileMode ) : BOOLEAN;
(* Returns TRUE if mode is a valid file access mode, otherwise FALSE. *)
END FileMode.

DecimalSep

INTERFACE MODULE DecimalSep;
(* Used for Formatted Output *)
TYPE Mode = ( Comma, Point );
PROCEDURE mode : Mode;
PROCEDURE SetMode ( mode : Mode );
(* default setting is locale dependent *)
END DecimalSep.

Tabulator

INTERFACE MODULE Tabulator; (* "\t" *)
TYPE Range = [0..80] OF CARDINAL;
PROCEDURE width : Range;
PROCEDURE SetWidth ( width : Range );
END Tabulator. (* default setting is 0 *)

NewLine

INTERFACE MODULE NewLine; (* "\n" *)
TYPE Mode = ( LF, CR, CRLF );
PROCEDURE mode : Mode;
PROCEDURE SetMode ( mode : Mode );
END NewLine. (* OS dependent default *)

Low-Level File IO

FilePtrIO

INTERFACE MODULE FilePtrIO; (* Low-Level File IO *)
IMPORT IOSize, IOStatus, FileMode;
CONST DefaultBufferSize = 1024*16; (*16 KOctets*)
TYPE File = OPAQUE POINTER; FilePos = ALIAS OF IOSize;
PROCEDURE defaultInFile : File;
PROCEDURE defaultOutFile : File;
PROCEDURE defaultErrFile : File;
PROCEDURE isValidAccessor ( file : File ) : BOOLEAN;
PROCEDURE isSpecialFile ( file : File ) : BOOLEAN;
PROCEDURE Open
  ( NEW file : File; CONST filename : ARRAY OF CHAR; mode : FileMode; VAR status : IOStatus );
PROCEDURE OpenWithBufferSize
  ( NEW file : File; CONST filename : ARRAY OF CHAR;
    mode : FileMode; bufSize : IOSize; VAR status : IOStatus );
PROCEDURE ReOpen ( file : File; mode : FileMode );
PROCEDURE statusOf ( file : File ) : IOStatus;
PROCEDURE StatusMsg ( file : File; status : IOStatus );
PROCEDURE SetStatus ( file : File; status : IOStatus; VAR valid : BOOLEAN );
PROCEDURE modeOf ( file : File ) : FileMode;
PROCEDURE nameLen ( file : File ) : CARDINAL;
PROCEDURE GetName ( file : File; VAR filename : ARRAY OF CHAR );
PROCEDURE eof ( file : File ) : BOOLEAN;
PROCEDURE currentPos ( file : File ) : FilePos;
PROCEDURE isValidPos ( file : File; pos : FilePos ) : BOOLEAN;
PROCEDURE lastValidSetPos ( file : File ) : FilePos;
PROCEDURE SetPos ( file : File; pos : FilePos );
PROCEDURE Advance ( file : File; offset : FilePos );
PROCEDURE Rewind ( file : File );
PROCEDURE dataReady ( file : File; octets : IOSize ) : BOOLEAN;
PROCEDURE ReadOctet ( file : File; VAR data : OCTET );
PROCEDURE ReadBlock ( file : File; VAR data : ARRAY OF OCTET );
PROCEDURE insertReady ( file : File ) : BOOLEAN;
PROCEDURE Insert ( file : File; data : OCTET );
PROCEDURE WriteOctet ( file : File; data : OCTET );
PROCEDURE WriteBlock ( file : File; data : ARRAY OF OCTET; VAR octetsWritten : IOSize );
PROCEDURE isFlushable ( file : File ) : BOOLEAN;
PROCEDURE Flush ( file : File );
PROCEDURE Close ( VAR file : File; VAR status : IOStatus );
END FilePtrIO.

FileDescIO

INTERFACE MODULE FileDescIO; (* Low-Level File IO *)
IMPORT IOSize, IOStatus, FileMode;
CONST InvalidFile = -1;
TYPE File = INTEGER;
  FilePos = ALIAS OF IOSize;
  RelPos = ALIAS OF LONGINT;
  From = ( Start, Current, End );
PROCEDURE defaultInFile : File;
PROCEDURE defaultOutFile : File;
PROCEDURE defaultErrFile : File;
PROCEDURE Open
  ( VAR fd : File; CONST filename : ARRAY OF CHAR; mode : FileMode; VAR status : IOStatus );
PROCEDURE modeOf ( fd : File ) : Mode;
PROCEDURE statusOf ( fd : File ) : IOStatus;
PROCEDURE isValidFile ( fd : File ) : BOOLEAN;
PROCEDURE isSpecialFile ( fd : File ) : BOOLEAN;
PROCEDURE Read ( fd : File; VAR data : OCTET );
PROCEDURE ReadBlock ( fd : File; VAR data : ARRAY OF OCTET; octetsRead : IOSize );
PROCEDURE ReadBlockAtOffset
  ( fd : File; VAR data : ARRAY OF OCTET; VAR octetsRead : IOSize; offset : FilePos );
PROCEDURE Write ( fd : File; data : OCTET );
PROCEDURE WriteBlock ( fd : File; CONST data : ARRAY OF OCTET; octetsWritten : IOSize );
PROCEDURE WriteBlockAtOffset
  ( fd : File; data : ARRAY OF OCTET; VAR octetsRead : IOSize; offset : FilePos );
PROCEDURE eof ( fd : File ) : BOOLEAN;
PROCEDURE SetPos ( fd : File; pos : FilePos );
PROCEDURE Advance ( fd : File; offset : FilePos );
PROCEDURE Rewind ( fd : File );
PROCEDURE SetRelPos ( fd : File; from : From; offset : RelPos; VAR newPos : FilePos );
PROCEDURE Close ( VAR fd : File; VAR status : IOStatus );
PROCEDURE CloseAll ( VAR status : IOStatus );
END FileDescIO.
Clone this wiki locally