ASCII file I/O in V4 ? 
Author Message
 ASCII file I/O in V4 ?

Hi everybody-

Is there a way to read and write ASCII files under V4?
API is not important, though "Files"-resemblance would
be nice. Or do I have to resort to {*filter*} tricks like
reading BYTEs and then doing some SYSTEM.VAL?
Every hint or clue is appreciated. Thanks in advance,
Ulf



Fri, 03 Dec 1999 03:00:00 GMT  
 ASCII file I/O in V4 ?

Quote:

> Hi everybody-

> Is there a way to read and write ASCII files under V4?
> API is not important, though "Files"-resemblance would
> be nice. Or do I have to resort to {*filter*} tricks like
> reading BYTEs and then doing some SYSTEM.VAL?
> Every hint or clue is appreciated. Thanks in advance,
> Ulf

Under ETH V4 for Windows one can Files.Old("&fileName")
(or Files.New) where the "&" causes Oberon to neither generate
or expect the 34 byte header on the file.  All Files.P
procedures can then be used for ASCII reading or writing.

-Doug

--

Senior Research Engineer        (415) 723-2487 x332
Center for the Study of Language and Information
Stanford University



Fri, 03 Dec 1999 03:00:00 GMT  
 ASCII file I/O in V4 ?



Quote:
> Is there a way to read and write ASCII files under V4?
> API is not important, though "Files"-resemblance would
> be nice. Or do I have to resort to {*filter*} tricks like
> reading BYTEs and then doing some SYSTEM.VAL?
> Every hint or clue is appreciated. Thanks in advance,
> Ulf

I am not an expert... I usually look at other people's
code to answer such questions. Linz Oberons come with
full source and this is where I look most often.
There is an EditTools.StoreAscii command which
obviously writes an ascii file. Let's have a look:

PROCEDURE StoreAscii*;   (*ww 21 Aug 91 / CAS 5-Nov-91*)
  VAR r: Texts.Reader;
        t: Texts.Text; f: Files.File;
        fr: Files.Rider; v: Viewers.Viewer;
        name, bak: ARRAY 64 OF CHAR;
        ch: CHAR; beg, end, time: LONGINT; i, res:
INTEGER;
BEGIN t := NIL;

(* here some code to deal with "*", "^" in command line -- WS *)

  IF (t # NIL) & (name # "") THEN UnmarkMenu(v);
    Str("EditTools.StoreAscii "); Str(name); Ch(" ");
    f := Files.New(name); Files.Set(fr, f, 0);
    Texts.OpenReader(r,t, 0); Texts.Read(r, ch);

(* here the real thing starts *)
    WHILE ~r.eot DO
      IF ch = 0DX THEN ch := 0AX END ;   (* for Unix ASCII files *)
      IF ch # Texts.ElemChar THEN Files.Write(fr, ch) END ;
      Texts.Read(r, ch)
    END ;
(* here the real thing ends *)

    COPY(name, bak); i := 0;
    WHILE bak[i] # 0X DO INC(i) END ;
    bak[i] := "."; bak[i + 1] := "B";
    bak[i + 2] := "a"; bak[i + 3] := "k"; bak[i + 4] := 0X;
    Files.Rename(name, bak, res);
    Files.Register(f); Int(Files.Pos(fr)); Ln
  END
END StoreAscii;

Seems pretty clear?

Wojtek

--

Nuclear Structure Research Lab, Univ. of Rochester
271 East River Rd, Rochester, NY 14627.
phone (716) 275 2524  fax (716) 473 5384
World Wide Web: http://www.*-*-*.com/ ~skulski



Fri, 03 Dec 1999 03:00:00 GMT  
 ASCII file I/O in V4 ?


Quote:

>Hi everybody-

>Is there a way to read and write ASCII files under V4?

This is either much harder or much easier than you think.  For example,
I read the class roster for our class and do much with it.  The roster is
provided in a "tabs delimited" ascii format that doesn't actually have tabs
in it. :-)

I desired entries like
MCINTOSH, AUBREY LEE$M$123456789$etc$CH$101
to turn into ascii files for consumption by windows NT like

set user=%McIntosh.Aubrey.L%
net user 123456789 /ADD
mkdir %users%\%user%
mkdir %users%\%users%\TA
cacls /t /e /g %user%:C

I have used several front ends to do this.  In all of them, I use "Texts" and
not "Files" to read the input file.  The primary reason for this is ease in
development and debugging, and I don't perceive any down side on the input
part of the operation.  To scan a name, I wrote my own routine such as
ScanName( S : Texts.Scanner )  which manages S.s, S.nextCh, S.class and
remains fully compatible with other uses of Texts.Scan.

The primary issue here is understanding and trusting Texts.Scan.  

On output, I again use Texts.  Again, this is so that I can drop it into a
viewer, see it immediately, change it and re-use it as input in another
debug cycle.  There appears to be almost the same routines in Files to emit
formatted I/O, but my own work habits are to develop it in the Texts
environment for simplicity.

When I drop the GUI to be able to roboproduce 500 output files, I set a
Texts.Reader to the beginning of the new text, create a new file to receive
the ascii output, and do

(*open*)
ch := Texts.Read( R, ch );
WHILE ~R.eot DO
 Files.Write( o, ch ); Texts.Read( R, ch )
END;
(*close*)

This code is taken pretty directly from EdiT.StoreAscii

--
A prudent parent neither ignores nor disturbs suprisingly quiet children.
1-512-374-0144 (d) \0145 (v) / isdn:Guest / BitSurfr
Try to connect, report what happens...



Fri, 03 Dec 1999 03:00:00 GMT  
 ASCII file I/O in V4 ?



Quote:

>> Hi everybody-

>> Is there a way to read and write ASCII files under V4?
>> API is not important, though "Files"-resemblance would
>> be nice. Or do I have to resort to {*filter*} tricks like
>> reading BYTEs and then doing some SYSTEM.VAL?
>> Every hint or clue is appreciated. Thanks in advance,
>> Ulf

> Under ETH V4 for Windows one can Files.Old("&fileName")
> (or Files.New) where the "&" causes Oberon to neither generate
> or expect the 34 byte header on the file.  All Files.P
> procedures can then be used for ASCII reading or writing.

The essential trick seems to be Files.Set at position 0
after opening the file. Then use Files procedures to
write to a file. The original Files from Project Oberon
had only Read/WriteBytes procedures, but these days are long gone.
Now Files has a whole bunch of procedures to read/write anything
you want in machine-independent format.

BTW, there is an elegant trick (due to Mssnbck I think) to
read/write 4-byte integers in variable number of bytes.
I saw it in one of Stefan Ludwig's program and used it
ever since.

Wojtek

--

Nuclear Structure Research Lab, Univ. of Rochester
271 East River Rd, Rochester, NY 14627.
phone (716) 275 2524  fax (716) 473 5384
World Wide Web: http://www.*-*-*.com/ ~skulski



Sat, 04 Dec 1999 03:00:00 GMT  
 ASCII file I/O in V4 ?


Quote:

>BTW, there is an elegant trick (due to Mssnbck I think) to
>read/write 4-byte integers in variable number of bytes.
>I saw it in one of Stefan Ludwig's program and used it
>ever since.

        Would you elaborate on this, or at least point us to the
relevent module?

Thanks,
Michael
--

"Aside from athletic talent, nothing is more helpful in getting
you a big shoe contract than being an {*filter*}."  --Robert Wright



Sun, 05 Dec 1999 03:00:00 GMT  
 ASCII file I/O in V4 ?


Quote:


> >BTW, there is an elegant trick (due to Mssnbck I think) to
> >read/write 4-byte integers in variable number of bytes.
> >I saw it in one of Stefan Ludwig's program and used it
> >ever since.

>    Would you elaborate on this, or at least point us to the
> relevent module?

> Thanks,
> Michael

Numbers can be encoded in a machine independent format (least significant byte first,
base 128, most significant bit as "stop bit", this bit cleared meaning stop).

I will try to explain that for positive and negative numbers separately:

For positive numbers, the loop is simply:
        writing the 7 least significant bits (plus adding 128, which makes it a number
                in the range 128..255, i.e. the most significant bit is set)
        shifting the number 7 bits to the right
After the loop, the number is <= 63, i.e. it can be represented with 6 bits, therefore the
most significant bit is not set.

For negative numbers we have to understand what x MOD 128 and x DIV 128 do:

I will motivate it with smaller numbers (x MOD 4 and x DIV 4):
x MOD y and x DIV y are defined in the language report as x = (x DIV y) * y + (x MOD y),
the result of the module operation is always positive.

x   x (binary)  x (bin, last 2 bits)  x MOD 4   x DIV 4
-1  1111 1111   11                    3         -1
-2  1111 1110   10                    2         -1
-3  1111 1101   01                    1         -1
-4  1111 1100   00                    0         -1
-5  1111 1011   11                    3         -1
-6  1111 1010   10                    2         -1

We see that x MOD 128 returns the 7 least significant bits and that x DIV 128 shifts
x 7 bits to the right.

Therefore, for negative numbers, the loop is simply:
        writing the 7 least siginificant bits (plus adding 128, as above)
        shifting the number 7 bits to the right
After the loop, the number is >= -64, x MOD 128 is in the range of 64..127 (see below),
i.e. the most significant bit is not set.

x    x (binary)      x MOD 128
-64  1111 1100 0000  100 0000 = 64
-63  1111 1100 0001  100 0001 = 65
-1   1111 1111 1111  111 1111 = 127

PROCEDURE  WriteNum* (VAR R: Rider; x: LONGINT);
BEGIN
        WHILE (x < - 64) OR (x > 63) DO Write(R, CHR(x MOD 128 + 128)); x := x DIV 128 END ;
        Write(R, CHR(x MOD 128))
END WriteNum;

The reverse operations are performed on reading the number:

For positive numbers:
The loop converts all the 7 bit chunks (which have the most significant bit set) by
        adding the number (decremented by 128 and shifted the appropriate number of bits to
        the left)
After the loop the number is <= 63 (see WriteNum), therefore ch MOD 64 is ch, x DIV 64 = 0,
which means that the number is simply shifted the appropriate number of bits and is added

For negative numbers:
The loop converts all the 7 bit chunks (which have the most significant bit set) by
        adding the number (decremented by 128 and shifted the appropriate number of bits to
        the left).
After the loop the number is in the range of 64..127 (see above), ch MOD 64 is 0..63,
(ch DIV 64) * 64 is 64, therefore ORD(ch) MOD 64 - ORD(ch) DIV 64 * 64 is in the range of
-64..-1. Shifting a negative number the appropriate number of bits to the left and adding it to
the previous sum yields the same negative number that we had before writing it with
WriteNum.

PROCEDURE  ReadNum* (VAR R: Rider; VAR x: LONGINT);
        VAR s: SHORTINT; ch: CHAR; n: LONGINT;
BEGIN s := 0; n := 0; Read(R, ch);
        WHILE ORD(ch) >= 128 DO INC(n, ASH(ORD(ch) - 128, s) ); INC(s, 7); Read(R, ch) END ;
        x := n + ASH(ORD(ch) MOD 64 - ORD(ch) DIV 64 * 64, s)
END ReadNum;

Note: The operations are very efficient for small numbers (-64..63) regarding the number
        of operations needed to read and write and also the number of bytes needed for
        binary representation.
The largest possible numbers (2147483647 for 4 byte integers) need only one byte overhead,
        most numbers are stored in a compact way thus saving space.

Example:
1567
WriteNum:
        (1567 MOD 128) + 128 = 159, (1567 DIV 128) = 12
Representation on file: 159     12
ReadNum:
        159 - 128 = 31, ASH(12, 7) = 1536, 1536 + 31 = 1567

-1567
WriteNum:
        (-1567 MOD 128) + 128 = 225, -1567 DIV 128 = -13, -13 MOD 128 = 115
Representation on file: 225     115
ReadNum
        225 - 128 = 97, 115 MOD 64 = 51, 115 DIV 64 * 64 = 64, 51 - 64 = -13, ASH(-13, 7) = -1664
        -1664 + 97 = -1567

2147483647
WriteNum
        2147483647 MOD 128 + 128 = 255, 2147483647 DIV 128 = 16777215
        16777215 MOD 128 + 128 = 255,   16777215 DIV 128 = 131071
        131071 MOD 128 + 128 = 255,     131071 DIV 128 = 1023
        1023 MOD 128 + 128 = 255,       1023 DIV 128 = 7
Representation on file: 255     255     255     255     7

The explanation has become a bit lenghty, but I think the ideas behind it are
nice enough!

Chris
--
DDipl.-Ing. Christoph Steindl               University of Linz
Phone: +43-732-2468-7134                    Practical Computer Science
Fax:   +43-732-2468-7138                    Freistaedterstrasse 315

http://www.ssw.uni-linz.ac.at/Staff/CS.html



Mon, 06 Dec 1999 03:00:00 GMT  
 ASCII file I/O in V4 ?

Quote:

>          IN ARTICLE elegant trick? (was: ASCII file I/O in V4 ?)



> > >BTW, there is an elegant trick (due to Mssnbck I think) to
> > >read/write 4-byte integers in variable number of bytes.
> > >I saw it in one of Stefan Ludwig's program and used it
> > >ever since.

> >       Would you elaborate on this, or at least point us to the
> > relevent module?

> > Thanks,
> > Michael

> Numbers can be encoded in a machine independent format (least
> significant byte first,
> base 128, most significant bit as "stop bit", this bit cleared meaning
> stop).

Is there a similar method for encoding floating-point numbers in
machine-independent format?

Thanks,
Geoff



Sat, 18 Dec 1999 03:00:00 GMT  
 ASCII file I/O in V4 ?


Quote:

> Is there a similar method for encoding floating-point numbers in
> machine-independent format?

Yes. It is called IEEE float format. AFAIK Oberon System uses this format
for storing floats, which are thus machine-independent.

Hope it helps.
Wojtek

--

Nuclear Structure Research Lab, Univ. of Rochester
271 East River Rd, Rochester, NY 14627.
phone (716) 275 2524  fax (716) 473 5384
World Wide Web: http://nuchem.nsrl.rochester.edu/~skulski



Sat, 18 Dec 1999 03:00:00 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. Need converter program to translate ascii to ebcdic in mixes ascii/binary file

2. Dectecting type of OS in V4?

3. New freeware Oberon System V4 for OS/2 2.1 released

4. VX-Rexx and OS/2 Warp V4

5. MF COBOL V4.0 OS/2 Animator Cross Session Problems

6. Export Clarion .DAT files to ASCII comma delimited files

7. how to export ASCII files from .TPS files ?

8. Export Clarion .DAT files to ASCII comma delimited files

9. Trouble importing ascii file into .tps database file.

10. reading ascii file and creating topspeed file in application designer - gasman.zip (0/2)

11. Exporting Clarion DAT file to ASCII(Text)File

12. Reading fortran text files / Parsing ascii files/ Help!!

 

 
Powered by phpBB® Forum Software