DEFINITION MODULE ByteBlockIO;
  (*******************************************************************
    Module  ByteBlockIO     (Version 1.0)
      Copyright (c) 1991-2006 by Dimitrios Gyalistras and ETH Zurich.
    Purpose   Sequential and random read/write access to an ARRAY OF BYTE.
    Remarks   - This module can be used to read/write a sequential text
	            file blockwise in memory.
	          - The procedures exported below are identical with the IO-
	            routines provided by module DMFiles (DM v2.02), with the
	            difference that they operate directly on computer memory
	            ("VAR f: TextFile" no more exists, all operations on current
	            byte block).
	          - There exist no IO-modes. Reading and writing within a
	            ByteBlock can be performed alternately, but each operation
	            will increment the current position in the same way.
    Programming
      o Design
        Dimitrios Gyalistras      10/01/1991
      o Implementation
        Dimitrios Gyalistras      10/01/1991
    ETH Zurich
    Systems Ecology
    CHN E 35.1
    Universitaetstrasse 16
    8092 Zurich
    SWITZERLAND
    URLs:
        <mailto:RAMSES@env.ethz.ch>
        <http://www.sysecol.ethz.ch>
        <http://www.sysecol.ethz.ch/SimSoftware/RAMSES>
    Last revision of definition:  10/01/1991  AF
  *******************************************************************)
  FROM SYSTEM IMPORT BYTE ;
  TYPE
    BlockAccessProcedure = PROC;
  PROCEDURE SetWorkBlock ( VAR buf: ARRAY OF BYTE; blockNr: LONGINT; used: LONGINT );
    (*
      Declare the current work array and set start position to 0.
      Declaration has no effect, if used<1 or blockNr<1. The case
      used>HIGH(buf)+1 is not checked allowing usage of pointers
      (e.g. buf equal ptr^). Read/Write may be performed sequentially
      within the address area given by bb (start address) and "bb+used-1"
     (stop address). No checks are performed by the
    *)
  PROCEDURE GetWorkBlock ( VAR blockNr: LONGINT; VAR used: LONGINT );
    (*
      Number and used bytes of current work object.
    *)
  VAR
    specifyPreviousWorkBlock,
    specifyNextWorkBlock     : BlockAccessProcedure ;
    (*
      PROC-variables above are initialized to 'DoNothing'.
      'specifyPreviousWorkBlock' is needed to guarantee
      correct execution of procedure 'Again',
      'specifyNextWorkBlock' to continue sequential IO in a next
      (other) piece of memory.
      Example for correct usage: see module TstByteBlockIO.MOD
    *)
  PROCEDURE GetBytePos( VAR pos:LONGINT );
    (*
      Returns current position in byte-block.
    *)
  PROCEDURE SetBytePos( pos: LONGINT );
    (*
      Sets new current position, if pos within valid bounds.
    *)
  PROCEDURE GetLineCount( VAR line: LONGINT );
    (*
      Returns line counter. The counter is initialized to 1D when
      calling "SetWorkBlock" and is incremented whenever "ReadChar"
      or "WriteChar" read/write ch=EOL. "Again" will decrement the
      line counter, if the current character before calling the
      procedure was = EOL.
    *)
  PROCEDURE SetLineCount( line: LONGINT );
    (*
      Sets line counter to new value.
    *)
  PROCEDURE ResetByteBlockIO;
    (*
      Call this procedure when finishing your IO in order to assign
      DoNothing to specifyPreviousWorkBlock and
      specifyNextWorkBlock and prevent erroneous read/write into
      memory.
    *)
  (*===== IO procedures analogous to those exported by DMFiles =====*)
  PROCEDURE EOF(): BOOLEAN;
    (*
      Returns TRUE, if end of current block reached and a call to
      specifyNextWorkBlock does not change the current block. Any
      changes in
    *)
  PROCEDURE Again;
  PROCEDURE ReadByte(VAR b: BYTE);
  PROCEDURE WriteByte(b: BYTE);
  CONST EOL = 36C; (*char returned by ReadChar if an end of line has
					 been encountered*)
  PROCEDURE ReadChar(VAR ch: CHAR);
  PROCEDURE SkipGap;
  PROCEDURE ReadChars(VAR string: ARRAY OF CHAR);
  PROCEDURE WriteChar(ch: CHAR);
  PROCEDURE WriteEOL; (* = Write(EOL) *)
  PROCEDURE WriteChars(string: ARRAY OF CHAR);
  VAR
	legalNum: BOOLEAN;	(*indicates whether read string conforms
						to legal Modula-2 number syntax*)
  PROCEDURE GetCardinal(VAR c: CARDINAL);
  PROCEDURE PutCardinal(c: CARDINAL; n: CARDINAL);
  PROCEDURE GetInteger(VAR i: INTEGER);
  PROCEDURE PutInteger(i: INTEGER; n: CARDINAL);
  PROCEDURE GetReal(VAR x: REAL);
  PROCEDURE PutReal(x: REAL; n, dec: CARDINAL);
  PROCEDURE PutRealSci(x: REAL; n: CARDINAL);
  PROCEDURE GetLongCard(VAR c: LONGCARD);	
  PROCEDURE GetLongInt(VAR i: LONGINT);
  PROCEDURE GetLongReal(VAR x: LONGREAL);
  PROCEDURE PutLongCard(lc: LONGCARD; n: CARDINAL);	
  PROCEDURE PutLongInt(li: LONGINT; n: CARDINAL);
  PROCEDURE PutLongReal(lr: LONGREAL; n,dec: CARDINAL);
  PROCEDURE PutLongRealSci(lr: LONGREAL; n,dec: CARDINAL);
END ByteBlockIO.