Re: ASCII text file module

Bruno Essmann (bessmann@iiic.ethz.ch)
Fri, 30 Aug 1996 00:28:44 +0200

I'm sorry that I have to add my $0.02 once again, but since this discussion
seems to pop up again and again I'd like to present a simple solution which
also shows why Oberon/F has ASCII-I/O *already* included.

The idea is to use the Text Subsystem, i.e. TextMappers (Scanners/Formatters)
are used to read from/write to the text model as usual.
However, instead of loading/saving the text model as an Oberon/F document
the text is written to a file using the built-in ASCII-converter.
The solution is fairly simple and adds only a few lines of code to initialize
the scanners/formatters...

I hope this helps,
Bruno

MODULE IOTest;

IMPORT
TextModels, TextMappers, TextViews, Math, Files, Converters, Stores,
DevLog; (* DevLog is only used by to output the data read *)

(* Auxiliary *)

PROCEDURE GetAsciiConverter (): Converters.Converter;
CONST (* these *may* be platform specific *)
AsciiImporter = "HostTextConv.ImportText";
AsciiExporter = "HostTextConv.ExportText";
VAR c: Converters.Converter;
BEGIN
c := Converters.list;
WHILE (c # NIL) & (c.imp # AsciiImporter) &
(c.exp # AsciiExporter) DO
c := c.next
END;
ASSERT(c # NIL, 60); (* Postcondition violated *)
RETURN c
END GetAsciiConverter;


(* Test *)

PROCEDURE Out*;
VAR m: TextModels.Model; f: TextMappers.Formatter; i: INTEGER;
BEGIN
(* Initialize text and formatter *)
m := TextModels.dir.New(); (* create new text model *)
f.ConnectTo(m); (* connect a formatter to it *)

(* Start output *)
f.WriteString("This is an ASCII test"); f.WriteLn;
f.WriteString("---------------------"); f.WriteLn;
f.WriteLn;
f.WriteString("Long Pi = ");
f.WriteRealForm(Math.LPi(), 16, 1, 3, ' '); f.WriteLn;
f.WriteString("Some other long reals"); f.WriteLn;
FOR i := 1 TO 10 DO f.WriteLReal(33 / i); f.WriteLn END;

(* Save to file using the ASCII converter *)
Converters.Export(Files.dir.This(""), "TEST.TXT", GetAsciiConverter(),
TextViews.dir.New(m)); (* conv needs a text view *)
END Out;

PROCEDURE In*;
VAR st: Stores.Store; m: TextModels.Model; s: TextMappers.Scanner;
BEGIN
(* Load ASCII text and initialize scanner *)
Converters.Import(Files.dir.This(""), "TEST.TXT", GetAsciiConverter(), st);
ASSERT(st IS TextViews.View, 20); (* should be a text view *)
m := st(TextViews.View).ThisModel(); (* get model of this text view *)
s.ConnectTo(m); (* connect the scanner *)
s.SetOpts({TextMappers.returnCtrlChars}); (* please customize *)

(* scan the file *)
s.Scan;
WHILE (s.type # TextMappers.eot) DO
CASE s.type OF
TextMappers.line, TextMappers.para: DevLog.Ln
| TextMappers.char: DevLog.Char(s.char)
| TextMappers.string: DevLog.String(s.string); DevLog.Char(" ")
| TextMappers.real: DevLog.LReal(s.real); DevLog.Char(" ")
ELSE (* ignore others for this sample *)
END;
s.Scan
END;
END In;

END IOTest.