Article View: comp.lang.modula2
Article #631Re: Of Mice & Modula-2/Random Files
From: Guenter Dotzel
Date: Mon, 31 Aug 1992 07:37
Date: Mon, 31 Aug 1992 07:37
256 lines
8518 bytes
8518 bytes
MWALLS%NMSU.EDU@USENET.ZER wrote on Sat, 08-29-1992 at 21:01 h
under the subject 'Of Mice & Modula-2':
> In BASIC you can open a Random (or Indexed) file by using the
> following: ...
> where record size is the number of bytes set aside per record.
>
> Then, at any time while it is open, one can get or put information
> into a specific point in the file by using: ...
> (where rec is the record to be accessed)
>
> Is there a way to do this in Modula-2. This is probably a stupid
> question, but I really don't know.
>
Yes, you *can* do that quite easily and portable in Modula-2 (see example
below), provided you have the ISO M2 Std Lib available.
***** Note,
***** We port this library to any popular platform on request, so
***** if anybody needs this library for his/her favorite compiler/platform,
***** please send email
----cut here------>
To Guenter Dotzel, email/internet: g_dotzel@ame.nbg.sub.org
We are using the _______ V___ Modula-2 compiler under ______ V____
We are using the _______ V___ Oberon-2 compiler under ______ V____
and would be happy to see an implementation of the ISO M2 Std Lib
for that compiler/system.
Best wishes, ....
<----cut here------
I'll post a summary/statistic for the requests received in Oct-92.
Also I'll provide a portation schedule for the top-most popular platforms.
Random File Access:
I've already posted the following random file access example and test programs
some months ago, but maybe its worth to post 200 lines of code again:
MODULE TestPos;
(* ISO Modula-2 I/O-Library test program for random file access.
This program runs under VAX/VMS using ModulaWare's compiler kit MVR V3.20.
This program also runs on the Mac with using p1 compiler/ISO M2 Std Lib.
An Oberon-2 version of this program is contained in a follow up message.
(c) 1992 by ModulaWare GmbH, written by Elmar Baumgart 10-Mar-1992,
27-Mar-1992 (skip multiple blank lines)
- If at the start of the program the hash table file DATA does not
exist, a new file is created and initialized.
Otherwise, the existing file called DATA is used.
- The program reads two files called INSERT and SEARCH. Both files
may have any text file format.
- inserts token strings from file INSERT into a hash-table file DATA
- searches token strings from file SEARCH in file DATA
*)
FROM ProgramArgs IMPORT IsArgPresent, ArgChan;
IMPORT STextIO, SWholeIO;
FROM IOResult IMPORT ReadResult, ReadResults;
FROM TextIO IMPORT WriteString, ReadToken, SkipLine, ReadString;
IMPORT SeqFile;
FROM RndFile IMPORT OpenClean, OpenOld, read, write, text, binary,
ChanId, OpenResults, Close, FilePos, SetPos, NewPos, StartPos;
FROM RawIO IMPORT Write, Read;
CONST
ITEMLENGTH = 40;
ITEMS = 3877; (*prime*) (*creates ITEMS * ITEMLENGTH hash-table on disk*)
DATA = 0; INSERT = 1; SEARCH = 2;
TYPE
WCproc = PROCEDURE(CARDINAL, CARDINAL);
WSproc = PROCEDURE(ARRAY OF CHAR);
ItemType = ARRAY[0..ITEMLENGTH-1] OF CHAR;
fnam = ARRAY[0..255] OF CHAR;
Args = ARRAY[DATA..SEARCH] OF fnam;
VAR
WC: WCproc; WS: WSproc; NL: PROC;
data, ins, sea: ChanId;
free: INTEGER;
file: Args;
startPos: FilePos;
PROCEDURE CalcPos(Key: CARDINAL): FilePos;
BEGIN
RETURN NewPos(data, Key, ITEMLENGTH, startPos);
END CalcPos;
PROCEDURE CalcKey(item: ARRAY OF CHAR): CARDINAL;
VAR len, i, key: CARDINAL;
BEGIN
len:= LENGTH(item);
key:= 1;
IF len > 0 THEN
FOR i:= 0 TO len-1 DO
key:= (key * (ORD(item[i]) MOD 26 + 1)) MOD ITEMS;
END;
END;
RETURN key;
END CalcKey;
PROCEDURE EQUAL(old, new: ARRAY OF CHAR): BOOLEAN;
VAR i: INTEGER; eq: BOOLEAN; len: INTEGER;
BEGIN
i:= 0; eq:= TRUE; len:= LENGTH(new);
WHILE (i < len) AND eq DO
eq:= old[i] = new[i]; INC(i);
END;
RETURN eq;
END EQUAL;
PROCEDURE Insert(item: ARRAY OF CHAR);
VAR Key, offset: CARDINAL; atPos: ItemType; eq: BOOLEAN;
BEGIN
IF free > 0 THEN
Key:= CalcKey(item);
SetPos(data, CalcPos(Key));
Read(data, atPos); offset:= 0;
eq:= EQUAL(atPos, item);
WHILE NOT eq AND (atPos[0] <> 0C) AND (offset < ITEMS) DO
IF ReadResult(data) = endOfInput THEN SetPos(data, startPos);
END;
Read(data, atPos);
eq:= EQUAL(atPos, item); INC(offset);
END;
IF eq THEN WS('already inserted');
ELSE
SetPos(data, CalcPos((Key + offset) MOD ITEMS));
Write(data, item);
WS(' inserted');
DEC(free);
END;
WC(offset, 4); WS(' "'); WS(item); WS('"'); NL;
ELSE WS('-table full-'); NL;
END;
END Insert;
PROCEDURE Search(item: ARRAY OF CHAR);
VAR Key, offset: CARDINAL; atPos: ItemType; eq: BOOLEAN;
BEGIN
Key:= CalcKey(item);
SetPos(data, CalcPos(Key));
Read(data, atPos); offset:= 0;
eq:= EQUAL(atPos, item);
WHILE NOT eq AND (atPos[0] <> 0C) AND (offset < ITEMS) DO
IF ReadResult(data) = endOfInput THEN SetPos(data, startPos);
END;
Read(data, atPos);
eq:= EQUAL(atPos, item); INC(offset);
END;
IF offset >= ITEMS THEN eq:= FALSE;
END;
IF eq THEN WS(' found');
ELSE WS('not found');
END;
WC(offset, 4); WS(' "'); WS(item); WS('"'); NL;
END Search;
PROCEDURE InsertIt;
VAR item: ItemType;
BEGIN
SeqFile.OpenRead(ins, file[INSERT], text, ores);
IF ores <> opened THEN WS('failed to open '); WS(file[INSERT]); NL;
ELSE
WS('Inserting token strings from file '); WS(file[INSERT]); NL;
ReadToken(ins, item);
WHILE ReadResult(ins) <> endOfInput DO
Insert(item);
ReadToken(ins, item);
WHILE ReadResult(ins) = endOfLine DO
SkipLine(ins);
ReadToken(ins, item);
END;
END;
SeqFile.Close(ins);
END;
END InsertIt;
PROCEDURE SearchIt;
VAR item: ItemType;
BEGIN
SeqFile.OpenRead(sea, file[SEARCH], text, ores);
IF ores <> opened THEN WS('failed to open '); WS(file[SEARCH]); NL;
ELSE
WS('Searching token strings from file '); WS(file[SEARCH]); NL;
ReadToken(sea, item);
WHILE ReadResult(sea) <> endOfInput DO
Search(item);
ReadToken(sea, item);
WHILE ReadResult(sea) = endOfLine DO
SkipLine(sea);
ReadToken(sea, item);
END;
END;
SeqFile.Close(sea);
END;
END SearchIt;
PROCEDURE TestIt;
BEGIN
InsertIt; NL;
SearchIt;
END TestIt;
VAR
ores: OpenResults;
empty: ItemType;
i: INTEGER; wrongArgs: BOOLEAN;
BEGIN
free:= ITEMS;
FOR i:= 0 TO ITEMLENGTH-1 DO empty[i]:= 0C;
END;
WC:= SWholeIO.WriteCard; WS:= STextIO.WriteString; NL:= STextIO.WriteLn;
i:= 0;
WHILE (ReadResult(ArgChan()) <> endOfInput) AND (i <= SEARCH) DO
ReadToken(ArgChan(), file[i]); INC(i);
END;
IF (ReadResult(ArgChan()) <> endOfInput) AND (i > SEARCH) THEN
OpenOld(data, file[DATA], read + write + binary, ores);
IF ores = noSuchFile THEN
OpenClean(data, file[DATA], read + write + binary, ores);
IF ores = opened THEN
FOR i:= 1 TO ITEMS DO Write(data, empty);
END;
startPos:= StartPos(data);
TestIt;
Close(data);
ELSE WS('data file not present, create failed'); NL;
END;
ELSIF ores = opened THEN
startPos:= StartPos(data);
i:= 0; Read(data, empty);
WHILE ReadResult(data) <> endOfInput DO INC(i); Read(data, empty);
IF empty[0] <> 0C THEN DEC(free);
END;
END;
IF i <> ITEMS THEN WS(file[DATA]); WS(' is of illegal size'); NL;
ELSE TestIt;
END;
Close(data);
ELSE WS('data file present, access failed'); NL;
END;
WC(free, 1); WS(' entries free in '); WS(file[DATA]); NL;
ELSE WS(' TESTPOS hash-file insert-file search-file '); NL;
END;
END TestPos.
Guenter Dotzel, ModulaWare GmbH, Wilhelmstr. 17A, D-W 8520 Erlangen/F.R.Germany
Modula-2 & Oberon-2 Compiler Manufactur (VAX/VMS, OS/2 and Unix-Platforms)
Tel. +49 (9131) 208395, Fax +49 (9131) 28205.
E-mail/Internet: 100023.2527@compuserve.com
g_dotzel@ame.nbg.sub.org
Technical Details
Message-ID:
<28V60357CV@tron.gun.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!mcsun!Germany.EU.net!unidui!flyer!easix!tron.gun.de!g_dotzelShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!mcsun!Germany.EU.net!unidui!flyer!easix!tron.gun.de!g_dotzel From: g_dotzel@tron.gun.de (Guenter Dotzel) Newsgroups: comp.lang.modula2 Subject: Re: Of Mice & Modula-2/Random Files Message-ID: <28V60357CV@tron.gun.de> Organization: TRON Public Mailbox, Neurath, Germany Date: Mon, 31 Aug 92 09:37:00 +0200 Lines: 257