The SIMULA FILE classes


Simula contains a hierarchy of files for both formatted and un-formatted I/O:

Note that all files share a common ancestor in the prefix hierarchy: "file". You can also create your own sub-classes of these files for further specialization.

Standard Input and Output

The two file objects Sysin (Infile) and Sysout (Printfile) are always connected to the standard input and output channel, respectively. A user program acts as if it were enclosed in the following inspect statements:

      inspect Sysin do
         inspect Sysout do
            <... user program ...>

In a program, all unqualified calls to Inimage, Inint etc will refer to Sysin (stdin) and all calls to Outimage, Outint etc to Sysout (stdout). stdin and stdout can be redirected in MPW in the customary fashion (< or >).

Note that some name clashes occur: an unqualified reference to Image, Pos, SetPos, Length or More will refer to Sysout, due to the ordering of the inspect's. If you wish to access Sysin's image (pos, ...) you write Sysin.Image (Sysin.Pos, ...)

Class FILE

The class File contains attributes common to all fileclasses. Identifiers in upper case letters are not accessible to the user program.
    class file(FILENAME); value FILENAME; text FILENAME;
    begin
          Boolean OPEN; ! true if the file is open ;
    
          text    procedure Filename; Filename:-copy(FILENAME);
          Boolean procedure Isopen;   isopen  :=OPEN;
          Boolean procedure Setaccess(mode);text mode ; ......;
    
          if filename==Notext then error("...");
          
    end --- File --- ;

Class Imagefile

The class Imagefile defines the common attributes for all image- (record-) oriented files. The text variable Image acts as the record buffer. The procedures SetPos, Pos, More and Length are introduced for reasons of convenience.
    File class Imagefile;
	begin
	   text Image;   ! -- the record buffer, created at "Open";
	   procedure SetPos(i); integer i; 
	      Image.SetPos(i);
	   integer procedure Pos;
	      Pos := Image.Pos;
	   Boolean procedure More;
	      More := Image.More;
	   integer procedure Length;
	      Length := Image.Length;
	end;

Class Infile

Infiles are record-oriented input files. For instance, the standard input file Sysin is an Infile.

    Imagefile class Infile;
	begin
	   Boolean procedure Open(FileImage); text FileImage; ...;
	   Boolean procedure Close; ...;
	   
	           procedure Inimage; ...; ! -- reads the next input record --> Image;
	   Boolean procedure inRecord; ...;
	   
	   Boolean procedure Endfile; ...;  ! -- true if endfile has been read;
	   
	   character procedure Inchar; ...;  
	   		! -- gets the next character from Image;
	   Boolean procedure Lastitem; ...;  
	   		! -- skips blanks and tabs, true if Endfile;
	   text procedure Intext(N); integer N;
			! -- a copy of the next N characters from Image;
	   integer procedure Inint;  
	   		! -- skips blanks and tabs, reads next 	integer;
	   long real procedure Inreal;  ! -- skips, reads next real;
	end;

Attributes of INFILE

inimage reads the next record to Image, pads with blanks if necessary. Sets Endfile to true and Image to "!25!" if end-of-file (next Inimage will give an error). Note that there is no "end-of-line" character in Simula.
inrecord as Inimage but does not pad with blanks. If the record is longer than Length only the first Length characters are read and inrecord returns the value TRUE. The remaining characters may be read with subsequent calls on inrecord.
Inchar if not More then Inimage; Inchar := Image.Getchar;
i.e. automatic inimage if Image exhausted, returns the character at Pos and increments Pos.
lastitem skips blanks and tabs (with Inchar), if end-of-file is met then returns true else returns false.
inint
inreal
skips blanks and tabs, returns the next integer (real), changes Pos to the character after the number.
intext returns a copy of the next N characters, which are read with Inchar, so Inimage is automatically called if necessary.


Class Outfile

Outfiles are record-oriented output files.
    File class Outfile;
	begin
	   Boolean procedure Open(Fileimage); text Fileimage; ...;
	   Boolean procedure Close; ...;
	   
	   procedure Outimage; ...;
	   procedure BreakOutimage; ...;
	   procedure OutRecord; ...;
	   
	   procedure Outchar(C); character C; ...;
	   procedure Outtext(T); text T; ...;
	   procedure Outint(Inum,Width); integer Inum,Width; ...;
	   procedure Outfix(Rnum,Ndec,Width); (long) real Rnum; 
	   		integer 	Ndec,Width; ...;
	   procedure Outreal(Rnum,Ndec,Width); (long) real Rnum; 
	   		integer 	Ndec,Width; ...;
	end;

Attributes of Outfile

Outimage Transfers the entire contents of Image + a NEW_LINE character to the external file. Then it fills Image with blanks and sets Pos to 1.
[ Note: on UNIX systems, the image has extra blanks stripped off before writing to the file. This is transparent to the programmer since these are restored upon reading.
BreakOutimage Outputs the contents of Image, up to Pos, without adding a "new line". Then it fills Image with blanks and sets Pos to 1. Mostly useful in interactive I/O, e.g. when writing a prompt.
Outrecord Transfers the contents of Image, up to Pos, to the external file. No blank-filling, Pos is set to 1.
Outchar
Outtext
Stores a character or a text in Image. Automatic Outimage if not enough room in Image.
Outint Edits an integer right-adjusted in the next Width positions of Image (automatic Outimage if necessary). Error if Width not large enough.
Width = 0: edits in exactly as many positions as necessary.
Width < 0: left-adjusted in -Width positions.
Outfix Analogous, real number in fix format with Ndec decimals.
Outreal Analogous, real number in scientific format.

Note:
since Intext/Outtext call Inbyte/Outbyte, also these routines will increment the ordinal number.

Class Printfile

Printfile is a subclass of Outfile, further specialized for line printer oriented output. The standard output file Sysout is a Printfile.

Outfile class Printfile;
begin
   Boolean procedure Open(Fileimage); text Fileimage; ...;
   Boolean procedure Close; ...;
   integer procedure Line;  ! -- return number of current line 
                                     (relative to page start);
   integer procedure Page;  ! -- return current page number;
   integer procedure LinesPerPage(N); integer N; ...; 
                                  ! -- set page size to N lines, return 
                                    -- previous value;
   procedure Spacing(N); integer N; ...;  
                                  ! -- set line distance to N (default 1);
   procedure Eject(N); ...; integer N;  
                                  ! -- position to line N, Eject(1) gives new page;
   procedure Outimage; ...; ! -- as in Outfile but increments line (& page) number;
   procedure Outrecord;...; ! -- analogous;
end;

Open & Close

Open" associates a file object with an external file and (for imagefiles) provides a record buffer for I/O. "Close" disassociates the object from the external file (and flushes buffers etc.). Both functions return true if the operation succeeded, false otherwise.

Example (copy the file "in" to "out"):


	ref(Infile) Input; 
	ref(Outfile) Output;
	Input :- new Infile("in");  
	if not Input.Open(Blanks(132)) then 
	   Error("Input file does not exist"); 
	Output :- new Outfile("out"); 
	Output.Open(Blanks(132));
	Input.Inimage;
	while not Input.Endfile do
	begin
	   Output.Image := Input.Image;
	   Output.Outimage; Input.Inimage;
	end;
	Input.Close; Output.Close;
A more efficient solution with shared buffers:
Open the output file in this way:
    Output.Open(INPUT.IMAGE);
    
then copy:
    while not Input.Endfile do
    begin
        Output.Outimage;  ! same buffer!;
        Input.Inimage;
    end;

Class DirectFile

A directfile is a record-oriented file where the individual records are addressable by ordinal numbers (1...). Directfiles contain all attributes of both Infiles and Outfiles (Inimage, Inint, ..., Outimage, Outint, ...), which function in the same way as in those classes, and in addition the following:

	Imagefile class Directfile;
	begin
	   integer procedure Location; ...;  ! -- current record number;
	   procedure Locate(N); integer N; ...;  
	   		! -- set current record number 	to N;
	   integer procedure LastLoc; ...;  
	   		! -- highest record number written;
	   integer procedure MaxLoc; ...;  
	   		! -- highest permissible record 	number;
	   Boolean procedure DeleteImage;  ! -- delete current record;
	end;

Attributes of DirectFile

Attributes of DirectFile
Location Gives access to the ordinal number of the current record (1..., set to 1 when the file is opened). Each call to Inimage or Outimage will increment the ordinal number by 1.
Locate Sets the current record number. No transfer to/from the external file is performed until Inimage/Outimage is called. If the number is > LastLoc, a call to Inimage will result in Endfile being true. If the number is <= LastLoc but refers to a record which has not been written, a call to Inimage will result in the Image being filled with null characters ('!0!').
LastLoc The largest ordinal number of any written record.
MaxLoc The highest permissible value of the record ordinal number.
DeleteImage Makes the current record "unwritten".

NOTE: The input routines (Inchar, Inint etc.) in directfiles skips all unwritten records.


DirectFile Class KeyFile

A KeyFile allows access by KEY to variable length records.

KeyFiles are not part of the Standard SIMULA language. They are a Montreal addition defined by the external CLASS Keyfile (which uses the "textUtil CLASS). These are available under the "-diro" SIM compiler option.


	Directfile class KeyFile( HashSize ); integer HashSize;
	begin
	   Procedure CLOSE; ... ;
	   Text Procedure READ  ( Key );       Text Key  ;
	   Procedure      WRITE ( Key, Data ); Text Key, Data  ;
	   Procedure      DELETE( Key );       Text Key;
	end;
To simplify use, the IMAGE length of a KeyFile is predefined at 60 and Keyfiles are opened automatically at creation. The user must still take care to CLOSE the file or else the FREELIST of available physical records will be corrupted.

Notes:

KeyFiles are made up of three parts:

  1. Record 1 keeps global information on the file (hashSize and address of first record on FREELIST)
  2. A hasharea of fixed size (determined at creation).
  3. An OVERFLOW area where synonyms and record continuations are kept

Attributes of KeyFile

Attributes of DirectFile
WRITE( Key, Data) Writes out a record with both Key and the Data. If a record with the same KEY already exists, it is overwritten
READ (Key) If a record with this Key exists, returns a text with the DATA of the record. If such a record is not found, returns a one byte text containing "!0!".
DELETE (Key) Removes the record with this key. NOP is such a record doesn't exist.
CLOSE Writes out the internal FreeList and updates RECORD 1.
Example of use:
	begin
		external class keyfile;
		external class textutil;
		
		ref(KeyFile) F;
		integer i;
		Text Key, data;
		
		F :- new KeyFile("t1.60",10);
		for i := 1 step 1 until 10 do 
		begin
			Key :- int_as_text(i);
			F.WRITE(Key,"Contenu de l'enregistrement.....");
		end;
		 
		F.DELETE( int_as_text(3) );
		
		for i := 1 step 1 until 10 do 
		begin
			Key :- int_as_text(i);
			data :- F.READ(Key);
			outint(i,3); outtext(Key & ": " & data); outimage;
		end;
		
		F.CLOSE;
	end

Bytefile

Bytefiles read and write files as continuous streams of bytes. The function ByteSize gives access to the number of bits in a byte, which is always 8 in the current implementation of Lund Simula.
class Bytefile;
begin
   short integer procedure ByteSize; ...;  ! -- returns 8;
end;

Inbytefile

Inbytefiles are byte-oriented sequential input files.
Bytefile class Inbytefile;
begin
   Boolean procedure Open; ...;  ! -- note that the byte buffer is internal to the file;
   Boolean procedure Close; ...;
   Boolean procedure Endfile; ...;  ! -- true if there are no more bytes to read;
   short integer procedure Inbyte; ...;  ! -- the ASCII number of the input byte, sets
                                                                       -- Endfile and returns 0 if no more bytes;
   text procedure Intext(T); text T;
   begin   ! -- fills the frame of the text T with successive input bytes;
      T.Setpos(1);
      while T.More and not Endfile do T.Putchar(Char(Inbyte);
       if Endfile then T.Setpos(T.Pos-1);
       Intext :- T.Sub(1,T.Pos-1);
   end;
end;

Outbytefile

Outbytefiles are byte-oriented sequential output files.
Bytefile class Outbytefile;
begin
   Boolean procedure Open; ...;  ! -- note that the byte buffer is internal to the file;
   Boolean procedure Close; ...;
   procedure Outbyte(X); short integer X; ...;  ! -- writes a byte X;
   procedure Outtext(T); text T;
   begin   ! -- outputs all the characters in T as bytes;
      T.Setpos(1);
      while T.More do
          Outbyte(Rank(T.Getchar));
    end;
end;

Directbytefile

Directbytefiles are byte-oriented direct-access files. The individual bytes are addressable by ordinal numbers. Directfiles contain all attributes of both Inbytefiles and Outbytefiles (Inbyte, Intext, Outbyte, Outtext), which function in the same way as in those classes, and in addition the following:
Bytefile class Directbytefile;
begin
   integer procedure Location; ...;  ! -- current byte number;
   procedure Locate(N); integer N; ...;  ! -- set current byte number to N;
   integer procedure LastLoc; ...;  ! -- highest byte number written;
   integer procedure MaxLoc; ...;  ! -- highest permissible byte number;
end;

Attributes of Directbytefile

Attributes of Directbytefile
Location Gives access to the ordinal number of the current byte (1..., set to 1 when the file is opened). Each call to Inbyte or Outbyte will increment the ordinal number by 1.
Locate Sets the current byte number. No transfer to/from the external file is performed until Inbyte/Outbyte is called. If the number is > LastLoc, a call to Inbyte will result in Endfile being true. If the number is <= LastLoc but refers to a byte which has not been written, a call to Inbyte will return 0.
LastLoc The largest ordinal number of any written byte.
MaxLoc The highest permissible value of the byte ordinal number.
Note:
since Intext/Outtext call Inbyte/Outbyte, also these routines will increment the ordinal number.

SetAccess

Boolean procedure Setaccess(Mode); text Mode; ...;
With this function you can control creation and other aspects of a file. The mode string is not case-sensitive. The function returns true if the call succeeds, false if it fails. The default values of the modes are given in the following table.

Mode: InXfile OutXfile DirectXfile Takes effect at
create NA AnyCreate NoCreate Open
purge NoPurge NoPurge NoPurge Close
append NA NoAppend NoAppend Open
readwrite NA NA ReadWrite Open

(NA = Not Applicable)

Setaccess example

Open a directfile: use existing file if it already exists, create it if it does not.

	
	ref(Directfile) DF;
	Outtext("Enter file name: "); BreakOutimage;
	Inimage;
	DF :- new Directfile(Sysin.Image.Strip);
	DF.Setaccess("AnyCreate");
	if not DF.Open(Blanks(30)) then
	   Error("Could not open " & DF.Filename);

Cause a temporary file to be deleted after use:

	inspect new Directbytefile("temp") do
	begin
	   Open;
	   ...;
	   Setaccess("Purge");
	   Close;
	end;

Create mode

Create The external file must not exist at Open; if it does, Open returns false. A new file is created by the environment.
NoCreate The external file MUST exist at Open.
AnyCreate If the external file does exist at Open, it is opened, otherwise a new file is created.
Note that "NoCreate" is the default for DirectXfiles!

Purge mode

Purge The external file is deleted by the environment when it is closed.
NoPurge The external file is not deleted.

Append mode

Append Output to the file is added to the existing contents of the file. For Directfiles, "Append" prohibits output before LastLoc.
NoAppend For sequential Outfiles, implies that, after Close, the external file will only contain the output produced while the file was open.

Readwrite mode

ReadOnly Output operations cannot be performed on the file.
WriteOnly Input operations cannot be performed.
ReadWrite Both input and output operations can be performed.
Note that the readwrite mode only is relevant for Directfiles.