next up previous contents index
Next: Sockets Up: No Title Previous: Files

Input and Output of Text

  The previous example resulted in a very inefficient program: reading the entire file to a list and process it afterwards is extremely memory consuming. A far better solution would be to process the file incrementally line by line. This pattern of reading files occurs in fact very often, thus we provide support for it.

Expanding TAB Characters Revisited

In Program gif the revised formulation of the Expand procedure is shown. As before the file objects are created, but now both files inherit from Open.text as well. This class provides methods for buffered input and output.

 

local 
   [SPACE TAB BS] = " \t\b"
   fun {Insert N Is}
      case N>0 then {Insert N-1 SPACE|Is} else Is end
   end
   fun {ScanLine Is TabStop N}
      case Is of nil then nil
      [] I|Ir then
         case I of !TAB then
            M=TabStop - (N mod TabStop) in 
            {Insert M {ScanLine Ir TabStop M+N}}
         [] !BS then I|{ScanLine Ir TabStop {Max 0 N-1}}
         else I|{ScanLine Ir TabStop N+1}
         end
      end
   end
   fun {Scan Rs TabStop}
      !Rs=getS(Is)|Rr in
      case Is==False then Rr=nil nil
      else putS({ScanLine Is TabStop 0})|{Scan Rr TabStop}
      end
   end
in
   proc {Expand TabStop InFile OutFile}
      Rs in
      create _ from Open.file Open.text
         with [init(name:InFile) Rs close]
      end
      create _ from Open.file Open.text
         with [init(name:OutFile flags:[write 'create' truncate])
               {Scan Rs TabStop} close]
      end
   end
end

The Incremental Expand Procedure

  The function Scan constrains its first argument to a list of tuples of the form getS(Is). This list of tuples is applied as a batch method to the file object for the input file. If the method getS reduces, its argument is constrained to either False, in case the end of the file is reached, or to a string. This string contains exactly one line of the input file (without a new line character). The expansion of TAB characters is done in the function ScanLine as before. The function Scan constrains its output to a list of tuples with label putS. The argument of the tuples are the expanded lines. The entire list built by Scan is processed as a batch method by the file object for the output file.

The Class Open.text

  Open.text   is a class, which can be used similarly to the C stdio library [2]. In particular, the class is usable in conjunction with the classes Open.file , Open.unixSocket , Open.internetSocket , and Open.pipe . The class has no public attributes and the following public feature:

feat error: P
   As for the class Open.file, see Section gif.

The class Open.text has the following methods.

getC(?I)
   Constrains I to the next character, or to False if the input is at the end. Note that if you create an object which inherits from Open.text as well as from Open.file, the method seek from the class Open.file does not work together with this method.
putC(+I)
   Writes the character I.
unGetC
   The last character read is written back to the input buffer and may be used again by getC. It is allowed only to unget one character.
getS(?SB)
   Constrains SB to the next line of the input as string, or to False if the input is at the end. SB does not contain the new line character. Note that if you create an object which inherits from Open.text as well as from Open.file, the method seek from the class Open.file does not work together with this method.
putS(+V)
   Writes the virtual string V. Note that a newline character is appended.
atEnd(?B)
   If the end of input is reached, B is constrained to True, otherwise to False.

!!! Attention !!!

dOpen(+DescI)
   See Section gif.

!!! Attention !!!

getDesc(?FileDescIB)
   See Section gif.


next up previous contents index
Next: Sockets Up: No Title Previous: Files



Sven Schmeier
Tue Sep 5 10:43:51 MET DST 1995